Compare commits
46 Commits
android-cl
...
android-cl
Author | SHA1 | Date | |
---|---|---|---|
c493e73889 | |||
2b7c280f5b | |||
23eab8a90a | |||
c59103eb76 | |||
f00a35ee09 | |||
af93725c01 | |||
3953301c57 | |||
2dab9d5d4f | |||
b77666fa26 | |||
eca931c1b5 | |||
86ae77701f | |||
c1ee0c4d9e | |||
e632b35862 | |||
20d2dcd891 | |||
61d5ba5a7c | |||
339f688b7c | |||
fed11e703a | |||
438df8142a | |||
7b3730be24 | |||
d6c20bafb3 | |||
b8998db3a3 | |||
9ab1c84878 | |||
2f3335d361 | |||
0e8d900ed4 | |||
2c7ce0b7c6 | |||
3e2bdacf89 | |||
64c32076a1 | |||
4d75ce7de1 | |||
269ae2f569 | |||
a42a4b2c99 | |||
96f5c2b488 | |||
09ab9779aa | |||
97ed0a3a8f | |||
ec6d225dc6 | |||
800a332691 | |||
45eae17561 | |||
092365cab2 | |||
c98c2f101d | |||
8e86634a41 | |||
7424e5b707 | |||
5175c937a9 | |||
2692a567ab | |||
2de971fb52 | |||
403b2e8cd9 | |||
22141e723a | |||
419758125e |
3
TODO
@ -1,6 +1,6 @@
|
||||
# Fixes
|
||||
|
||||
- Better addressbook column widths
|
||||
- Better twopane column widths
|
||||
<zzz> on the i2ptunnel and addressbook pages on the tablet, the columns are too skinny, they aren't as wide as the tab
|
||||
<zzz> only a few addressbook entries wrap but on i2ptunnel everything is wrapped and most of the screen is empty
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
<zzz> spewing UPnP out into cell networks is a waste of time at best and a security risk at worst, but you really want it for wifi
|
||||
- Display release notes directly on new router version
|
||||
- Fill out help pages
|
||||
- Proper browser configuration page
|
||||
- Rewrite release notes to be release-specific
|
||||
- Fix release notes UI, either make back button use clear or add buttons
|
||||
- NetDB tablet view fixes
|
||||
|
@ -5,6 +5,8 @@ android {
|
||||
compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
|
||||
buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION
|
||||
defaultConfig {
|
||||
versionCode 4745223
|
||||
versionName '0.9.16-rc1'
|
||||
minSdkVersion 9
|
||||
targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
|
||||
}
|
||||
@ -37,19 +39,21 @@ android {
|
||||
dependencies {
|
||||
compile project(':routerjars')
|
||||
compile project(':client')
|
||||
compile 'com.android.support:support-v4:21.0.0'
|
||||
compile 'com.android.support:appcompat-v7:21.0.0'
|
||||
compile 'com.android.support:recyclerview-v7:21.0.0'
|
||||
compile 'com.android.support:cardview-v7:21.0.0'
|
||||
compile 'com.android.support:support-v4:21.0.2'
|
||||
compile 'com.android.support:appcompat-v7:21.0.2'
|
||||
compile 'com.android.support:recyclerview-v7:21.0.2'
|
||||
compile 'com.android.support:cardview-v7:21.0.2'
|
||||
compile 'net.i2p.android.ext:floatingactionbutton:1.1.0'
|
||||
compile files('libs/androidplot-core-0.6.1.jar')
|
||||
}
|
||||
|
||||
dependencyVerification {
|
||||
verify = [
|
||||
'com.android.support:support-v4:199ef7bb169386c80b4836354df6747ce2ae3d24434db923c22439e47106a1e2',
|
||||
'com.android.support:appcompat-v7:45e999dda55fe81d9cc1c7342b7b70480ff3f307baa8da0df767f92fc5c52cd1',
|
||||
'com.android.support:recyclerview-v7:ab2390d688601b65e2f3a0718b3d25487e61546c4e20f81eb0b033f30ca15b31',
|
||||
'com.android.support:cardview-v7:7b724eb46efc98eee70c333cd0e9c34ca89b1a4456c3e40cfcc33501c43570bf',
|
||||
'com.android.support:support-v4:126a4c291f41f75f3fff4968e9d397bc8454cdff4d8f994cbe0524e3bad76e72',
|
||||
'com.android.support:appcompat-v7:b760fd3d0b0b0547a1bcef9031b40939f31049ba955f04c8fdc5aa09a25d19e9',
|
||||
'com.android.support:recyclerview-v7:71ef0f5659b3019dc33c5ffb346ea01df1f66735506f38d43fd783fbcb0370ce',
|
||||
'com.android.support:cardview-v7:cb4d7ee9ebb6edffa7203eff0d207b4e88425599a8ed37d94b650bc84390c4eb',
|
||||
'net.i2p.android.ext:floatingactionbutton:84cf5b67a66337bef59b46f57468c730387ca766b5a5f06ca852ba46cabbc0fb',
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="net.i2p.android.router"
|
||||
android:installLocation="auto"
|
||||
android:versionCode="4745222"
|
||||
android:versionName="0.9.15.1">
|
||||
android:installLocation="auto">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="9"
|
||||
android:targetSdkVersion="19" />
|
||||
|
||||
<application
|
||||
android:icon="@drawable/ic_launcher_itoopie"
|
||||
android:label="@string/app_name"
|
||||
@ -59,6 +53,14 @@
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="net.i2p.android.router.MainActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name="net.i2p.android.help.BrowserConfigActivity"
|
||||
android:label="Browser Configuration"
|
||||
android:parentActivityName=".MainActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="net.i2p.android.router.MainActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".LicenseActivity"
|
||||
android:label="I2P License Information"
|
||||
@ -94,7 +96,7 @@
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".addressbook.AddressbookSettingsActivity"
|
||||
android:label="I2P Addressbook Settings"
|
||||
android:label="Addressbook Settings"
|
||||
android:launchMode="singleTop"
|
||||
android:parentActivityName=".addressbook.AddressbookActivity">
|
||||
<meta-data
|
||||
|
82
app/src/main/java/net/i2p/android/help/Browser.java
Normal file
@ -0,0 +1,82 @@
|
||||
package net.i2p.android.help;
|
||||
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
public class Browser implements Comparable<Browser> {
|
||||
public final String packageName;
|
||||
public final CharSequence label;
|
||||
public final Drawable icon;
|
||||
public final boolean isInstalled;
|
||||
public final boolean isKnown;
|
||||
public final boolean isSupported;
|
||||
public final boolean isRecommended;
|
||||
|
||||
/**
|
||||
* A browser that we don't know about.
|
||||
*
|
||||
* @param pm the PackageManager used to find the browser
|
||||
* @param browser the browser
|
||||
*/
|
||||
public Browser(PackageManager pm, ResolveInfo browser) {
|
||||
this(
|
||||
browser.activityInfo.packageName,
|
||||
browser.loadLabel(pm),
|
||||
browser.loadIcon(pm),
|
||||
true, false, false, false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A browser that we know about.
|
||||
*
|
||||
* @param pm the PackageManager used to find the browser
|
||||
* @param browser the browser
|
||||
* @param supported can this browser be used with I2P?
|
||||
*/
|
||||
public Browser(PackageManager pm, ResolveInfo browser, boolean supported, boolean recommended) {
|
||||
this(
|
||||
browser.activityInfo.packageName,
|
||||
browser.loadLabel(pm),
|
||||
browser.loadIcon(pm),
|
||||
true, true, supported, recommended
|
||||
);
|
||||
}
|
||||
|
||||
public Browser(String pn, CharSequence l, Drawable ic, boolean i, boolean k, boolean s, boolean r) {
|
||||
packageName = pn;
|
||||
label = l;
|
||||
icon = ic;
|
||||
isInstalled = i;
|
||||
isKnown = k;
|
||||
isSupported = s;
|
||||
isRecommended = r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Browser browser) {
|
||||
// Sort order: supported -> unknown -> unsupported
|
||||
int a = getOrder(this);
|
||||
int b = getOrder(browser);
|
||||
|
||||
if (a < b)
|
||||
return -1;
|
||||
else if (a > b)
|
||||
return 1;
|
||||
|
||||
return label.toString().compareTo(browser.label.toString());
|
||||
}
|
||||
|
||||
private static int getOrder(Browser browser) {
|
||||
if (browser.isKnown) {
|
||||
if (browser.isRecommended)
|
||||
return 0;
|
||||
else if (browser.isSupported)
|
||||
return 1;
|
||||
else
|
||||
return 3;
|
||||
} else
|
||||
return 2;
|
||||
}
|
||||
}
|
117
app/src/main/java/net/i2p/android/help/BrowserAdapter.java
Normal file
@ -0,0 +1,117 @@
|
||||
package net.i2p.android.help;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.ColorMatrix;
|
||||
import android.graphics.ColorMatrixColorFilter;
|
||||
import android.net.Uri;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
|
||||
public class BrowserAdapter extends RecyclerView.Adapter<BrowserAdapter.ViewHolder> {
|
||||
private Context mCtx;
|
||||
private Browser[] mBrowsers;
|
||||
private OnBrowserSelectedListener mListener;
|
||||
|
||||
// Provide a reference to the views for each data item
|
||||
// Complex data items may need more than one view per item, and
|
||||
// you provide access to all the views for a data item in a view holder
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
public ImageView mIcon;
|
||||
public TextView mLabel;
|
||||
public ImageView mStatus;
|
||||
|
||||
public ViewHolder(View v) {
|
||||
super(v);
|
||||
mIcon = (ImageView) v.findViewById(R.id.browser_icon);
|
||||
mLabel = (TextView) v.findViewById(R.id.browser_label);
|
||||
mStatus = (ImageView) v.findViewById(R.id.browser_status_icon);
|
||||
}
|
||||
}
|
||||
|
||||
public static interface OnBrowserSelectedListener {
|
||||
public void onBrowserSelected(Browser browser);
|
||||
}
|
||||
|
||||
public BrowserAdapter(Context ctx, OnBrowserSelectedListener listener) {
|
||||
mCtx = ctx;
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
public void setBrowsers(Browser[] browsers) {
|
||||
mBrowsers = browsers;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
mBrowsers = null;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
// Create new views (invoked by the layout manager)
|
||||
@Override
|
||||
public BrowserAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
|
||||
int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.listitem_browser, parent, false);
|
||||
return new ViewHolder(v);
|
||||
}
|
||||
|
||||
// Replace the contents of a view (invoked by the layout manager)
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
final Browser browser = mBrowsers[position];
|
||||
holder.mIcon.setImageDrawable(browser.icon);
|
||||
holder.mLabel.setText(browser.label);
|
||||
|
||||
if (browser.isKnown) {
|
||||
if (browser.isRecommended && browser.isInstalled) {
|
||||
holder.mStatus.setImageDrawable(
|
||||
mCtx.getResources().getDrawable(R.drawable.ic_stars_white_24dp));
|
||||
holder.mStatus.setVisibility(View.VISIBLE);
|
||||
} else if (browser.isSupported && !browser.isInstalled) {
|
||||
holder.mStatus.setImageDrawable(
|
||||
mCtx.getResources().getDrawable(R.drawable.ic_shop_white_24dp));
|
||||
holder.mStatus.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
String uriMarket = "market://search?q=pname:" + browser.packageName;
|
||||
Uri uri = Uri.parse(uriMarket);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||
mCtx.startActivity(intent);
|
||||
}
|
||||
});
|
||||
holder.mStatus.setVisibility(View.VISIBLE);
|
||||
} else if (!browser.isSupported) {
|
||||
// Make the icon gray-scale to show it is unsupported
|
||||
ColorMatrix matrix = new ColorMatrix();
|
||||
matrix.setSaturation(0);
|
||||
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
|
||||
holder.mIcon.setColorFilter(filter);
|
||||
holder.mLabel.setTextColor(
|
||||
mCtx.getResources().getColor(R.color.primary_text_disabled_material_dark));
|
||||
}
|
||||
}
|
||||
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mListener.onBrowserSelected(browser);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Return the size of the dataset (invoked by the layout manager)
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (mBrowsers != null)
|
||||
return mBrowsers.length;
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
package net.i2p.android.help;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class BrowserConfigActivity extends ActionBarActivity implements
|
||||
BrowserAdapter.OnBrowserSelectedListener {
|
||||
|
||||
/**
|
||||
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
|
||||
* device.
|
||||
*/
|
||||
private boolean mTwoPane;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_help);
|
||||
|
||||
// Set the action bar
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.main_toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
if (findViewById(R.id.detail_fragment) != null) {
|
||||
// The detail container view will be present only in the
|
||||
// large-screen layouts (res/values-large and
|
||||
// res/values-sw600dp). If this view is present, then the
|
||||
// activity should be in two-pane mode.
|
||||
mTwoPane = true;
|
||||
}
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.add(R.id.main_fragment, new BrowserListFragment())
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
onBackPressed();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
// BrowserAdapter.OnBrowserSelected
|
||||
|
||||
@Override
|
||||
public void onBrowserSelected(Browser browser) {
|
||||
int file;
|
||||
if (browser.isKnown) {
|
||||
if (browser.isSupported) {
|
||||
// Check for embedded browser
|
||||
if (browser.packageName.startsWith("net.i2p.android"))
|
||||
file = R.raw.help_embedded_browser;
|
||||
else {
|
||||
// Load the configuration guide for this browser
|
||||
try {
|
||||
String name = "help_" + browser.packageName.replace('.', '_');
|
||||
Class res = R.raw.class;
|
||||
Field field = res.getField(name);
|
||||
file = field.getInt(null);
|
||||
} catch (Exception e) {
|
||||
file = R.raw.help_unknown_browser;
|
||||
}
|
||||
}
|
||||
} else
|
||||
file = R.raw.help_unsupported_browser;
|
||||
} else
|
||||
file = R.raw.help_unknown_browser;
|
||||
HelpHtmlFragment configFrag = HelpHtmlFragment.newInstance(file);
|
||||
if (mTwoPane) {
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.detail_fragment, configFrag)
|
||||
.commit();
|
||||
} else {
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.main_fragment, configFrag)
|
||||
.addToBackStack("config" + browser.packageName)
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
}
|
187
app/src/main/java/net/i2p/android/help/BrowserListFragment.java
Normal file
@ -0,0 +1,187 @@
|
||||
package net.i2p.android.help;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.util.BetterAsyncTaskLoader;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BrowserListFragment extends Fragment implements
|
||||
LoaderManager.LoaderCallbacks<List<Browser>> {
|
||||
private static final int BROWSER_LOADER_ID = 1;
|
||||
|
||||
private BrowserAdapter.OnBrowserSelectedListener mCallback;
|
||||
private BrowserAdapter mAdapter;
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
|
||||
// This makes sure that the container activity has implemented
|
||||
// the callback interface. If not, it throws an exception
|
||||
try {
|
||||
mCallback = (BrowserAdapter.OnBrowserSelectedListener) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString()
|
||||
+ " must implement OnBrowserSelectedListener");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.fragment_help_browsers, container, false);
|
||||
RecyclerView mRecyclerView = (RecyclerView) v.findViewById(R.id.browser_list);
|
||||
|
||||
// use a linear layout manager
|
||||
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
|
||||
mRecyclerView.setLayoutManager(mLayoutManager);
|
||||
|
||||
mAdapter = new BrowserAdapter(getActivity(), mCallback);
|
||||
mRecyclerView.setAdapter(mAdapter);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
getLoaderManager().initLoader(BROWSER_LOADER_ID, null, this);
|
||||
}
|
||||
|
||||
// LoaderManager.LoaderCallbacks<List<Browser>>
|
||||
|
||||
@Override
|
||||
public Loader<List<Browser>> onCreateLoader(int id, Bundle args) {
|
||||
return new BrowserLoader(getActivity());
|
||||
}
|
||||
|
||||
public static class BrowserLoader extends BetterAsyncTaskLoader<List<Browser>> {
|
||||
private List<String> recommended;
|
||||
private List<String> recommendedLabels;
|
||||
private List<String> supported;
|
||||
private List<String> supportedLabels;
|
||||
private List<String> unsupported;
|
||||
|
||||
public BrowserLoader(Context context) {
|
||||
super(context);
|
||||
recommended = Arrays.asList(
|
||||
getContext().getResources().getStringArray(R.array.recommended_browsers));
|
||||
recommendedLabels = Arrays.asList(
|
||||
getContext().getResources().getStringArray(R.array.recommended_browser_labels));
|
||||
supported = Arrays.asList(
|
||||
getContext().getResources().getStringArray(R.array.supported_browsers));
|
||||
supportedLabels = Arrays.asList(
|
||||
getContext().getResources().getStringArray(R.array.supported_browser_labels));
|
||||
unsupported = Arrays.asList(
|
||||
context.getResources().getStringArray(R.array.unsupported_browsers));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Browser> loadInBackground() {
|
||||
List<Browser> browsers = new ArrayList<Browser>();
|
||||
Map<String, String> recommendedMap = new HashMap<String, String>();
|
||||
for (int i = 0; i < recommended.size(); i++) {
|
||||
recommendedMap.put(recommended.get(i), recommendedLabels.get(i));
|
||||
}
|
||||
Map<String, String> supportedMap = new HashMap<String, String>();
|
||||
for (int i = 0; i < supported.size(); i++) {
|
||||
supportedMap.put(supported.get(i), supportedLabels.get(i));
|
||||
}
|
||||
|
||||
// Find all installed browsers that listen for ".i2p"
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setData(Uri.parse("http://stats.i2p"));
|
||||
|
||||
final PackageManager pm = getContext().getPackageManager();
|
||||
List<ResolveInfo> installedBrowsers = pm.queryIntentActivities(intent, 0);
|
||||
|
||||
for (ResolveInfo browser : installedBrowsers) {
|
||||
if (recommended.contains(browser.activityInfo.packageName)) {
|
||||
browsers.add(new Browser(pm, browser, true, true));
|
||||
recommendedMap.remove(browser.activityInfo.packageName);
|
||||
} else if (supported.contains(browser.activityInfo.packageName) ||
|
||||
browser.activityInfo.packageName.startsWith("net.i2p.android")) {
|
||||
browsers.add(new Browser(pm, browser, true, false));
|
||||
supportedMap.remove(browser.activityInfo.packageName);
|
||||
} else if (unsupported.contains(browser.activityInfo.packageName))
|
||||
browsers.add(new Browser(pm, browser, false, false));
|
||||
else
|
||||
browsers.add(new Browser(pm, browser));
|
||||
}
|
||||
|
||||
// Now add the remaining recommended and supported browsers
|
||||
for (Map.Entry<String, String> browser : recommendedMap.entrySet()) {
|
||||
browsers.add(new Browser(browser.getKey(), browser.getValue(),
|
||||
getDrawableForPackage(browser.getKey()),
|
||||
false, true, true, true));
|
||||
}
|
||||
for (Map.Entry<String, String> browser : supportedMap.entrySet()) {
|
||||
browsers.add(new Browser(browser.getKey(), browser.getValue(),
|
||||
getDrawableForPackage(browser.getKey()),
|
||||
false, true, true, false));
|
||||
}
|
||||
|
||||
Collections.sort(browsers);
|
||||
return browsers;
|
||||
}
|
||||
private Drawable getDrawableForPackage(String packageName) {
|
||||
try {
|
||||
String name = "icon_" + packageName.replace('.', '_');
|
||||
Class res = R.drawable.class;
|
||||
Field field = res.getField(name);
|
||||
int drawable = field.getInt(null);
|
||||
return getContext().getResources().getDrawable(drawable);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStartMonitoring() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStopMonitoring() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void releaseResources(List<Browser> data) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<List<Browser>> listLoader, List<Browser> browsers) {
|
||||
if (listLoader.getId() == BROWSER_LOADER_ID)
|
||||
mAdapter.setBrowsers(browsers.toArray(new Browser[browsers.size()]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<List<Browser>> listLoader) {
|
||||
if (listLoader.getId() == BROWSER_LOADER_ID)
|
||||
mAdapter.clear();
|
||||
}
|
||||
}
|
@ -2,27 +2,17 @@ package net.i2p.android.help;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.SpinnerAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.i2p.android.router.LicenseActivity;
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.dialog.TextResourceDialog;
|
||||
|
||||
import org.sufficientlysecure.htmltextview.HtmlTextView;
|
||||
|
||||
public class HelpActivity extends ActionBarActivity {
|
||||
public class HelpActivity extends ActionBarActivity implements
|
||||
HelpListFragment.OnEntrySelectedListener {
|
||||
public static final String CATEGORY = "help_category";
|
||||
public static final int CAT_MAIN = 0;
|
||||
public static final int CAT_CONFIGURE_BROWSER = 1;
|
||||
@ -40,30 +30,10 @@ public class HelpActivity extends ActionBarActivity {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_help);
|
||||
|
||||
final ActionBar actionBar = getSupportActionBar();
|
||||
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
|
||||
|
||||
SpinnerAdapter spinnerAdapter = ArrayAdapter.createFromResource(this,
|
||||
R.array.help_categories, android.R.layout.simple_spinner_dropdown_item);
|
||||
|
||||
ActionBar.OnNavigationListener navigationListener = new ActionBar.OnNavigationListener() {
|
||||
@Override
|
||||
public boolean onNavigationItemSelected(int i, long l) {
|
||||
showCategory(i);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
actionBar.setListNavigationCallbacks(spinnerAdapter, navigationListener);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
int category = getIntent().getIntExtra(CATEGORY, CAT_MAIN);
|
||||
// TODO remove when addressbook and I2PTunnel help added
|
||||
if (category > CAT_CONFIGURE_BROWSER)
|
||||
category = CAT_MAIN;
|
||||
actionBar.setSelectedNavigationItem(category);
|
||||
showCategory(category);
|
||||
}
|
||||
// Set the action bar
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.main_toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
if (findViewById(R.id.detail_fragment) != null) {
|
||||
// The detail container view will be present only in the
|
||||
@ -72,59 +42,16 @@ public class HelpActivity extends ActionBarActivity {
|
||||
// activity should be in two-pane mode.
|
||||
mTwoPane = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void showCategory(int category) {
|
||||
Fragment f;
|
||||
switch (category) {
|
||||
case CAT_CONFIGURE_BROWSER:
|
||||
//f = new BrowserConfigFragment();
|
||||
f = HelpHtmlFragment.newInstance(R.raw.help_configure_browser);
|
||||
break;
|
||||
|
||||
case CAT_ADDRESSBOOK:
|
||||
f = HelpHtmlFragment.newInstance(R.raw.help_addressbook);
|
||||
break;
|
||||
|
||||
case CAT_I2PTUNNEL:
|
||||
f = HelpHtmlFragment.newInstance(R.raw.help_i2ptunnel);
|
||||
break;
|
||||
|
||||
case CAT_MAIN:
|
||||
default:
|
||||
f = HelpHtmlFragment.newInstance(R.raw.help_main);
|
||||
break;
|
||||
if (savedInstanceState == null) {
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.add(R.id.main_fragment, new HelpListFragment())
|
||||
.commit();
|
||||
}
|
||||
|
||||
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
|
||||
ft.replace(R.id.main_fragment, f);
|
||||
if (mTwoPane)
|
||||
ft.remove(getSupportFragmentManager().findFragmentById(R.id.detail_fragment));
|
||||
ft.commit();
|
||||
}
|
||||
|
||||
public static class HelpHtmlFragment extends Fragment {
|
||||
public static final String ARG_HTML_FILE = "htmlFile";
|
||||
|
||||
static HelpHtmlFragment newInstance(int htmlFile) {
|
||||
HelpHtmlFragment f = new HelpHtmlFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ARG_HTML_FILE, htmlFile);
|
||||
f.setArguments(args);
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
ScrollView scroller = new ScrollView(getActivity());
|
||||
HtmlTextView text = new HtmlTextView(getActivity());
|
||||
scroller.addView(text);
|
||||
int padH = getResources().getDimensionPixelOffset(R.dimen.activity_horizontal_margin);
|
||||
int padV = getResources().getDimensionPixelOffset(R.dimen.activity_vertical_margin);
|
||||
text.setPadding(padH, padV, padH, padV);
|
||||
text.setHtmlFromRawResource(getActivity(), getArguments().getInt(ARG_HTML_FILE), true);
|
||||
return scroller;
|
||||
}
|
||||
int category = getIntent().getIntExtra(CATEGORY, -1);
|
||||
if (category >= 0)
|
||||
showCategory(category);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -136,21 +63,63 @@ public class HelpActivity extends ActionBarActivity {
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_help_licenses:
|
||||
Intent lic = new Intent(HelpActivity.this, LicenseActivity.class);
|
||||
startActivity(lic);
|
||||
return true;
|
||||
case R.id.menu_help_release_notes:
|
||||
TextResourceDialog dialog = new TextResourceDialog();
|
||||
Bundle args = new Bundle();
|
||||
args.putString(TextResourceDialog.TEXT_DIALOG_TITLE,
|
||||
getResources().getString(R.string.label_release_notes));
|
||||
args.putInt(TextResourceDialog.TEXT_RESOURCE_ID, R.raw.releasenotes_txt);
|
||||
dialog.setArguments(args);
|
||||
dialog.show(getSupportFragmentManager(), "release_notes");
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
case android.R.id.home:
|
||||
onBackPressed();
|
||||
return true;
|
||||
case R.id.menu_help_licenses:
|
||||
Intent lic = new Intent(HelpActivity.this, LicenseActivity.class);
|
||||
startActivity(lic);
|
||||
return true;
|
||||
case R.id.menu_help_release_notes:
|
||||
TextResourceDialog dialog = new TextResourceDialog();
|
||||
Bundle args = new Bundle();
|
||||
args.putString(TextResourceDialog.TEXT_DIALOG_TITLE,
|
||||
getResources().getString(R.string.label_release_notes));
|
||||
args.putInt(TextResourceDialog.TEXT_RESOURCE_ID, R.raw.releasenotes_txt);
|
||||
dialog.setArguments(args);
|
||||
dialog.show(getSupportFragmentManager(), "release_notes");
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
// HelpListFragment.OnEntrySelectedListener
|
||||
|
||||
@Override
|
||||
public void onEntrySelected(int entry) {
|
||||
if (entry == CAT_CONFIGURE_BROWSER) {
|
||||
Intent i = new Intent(this, BrowserConfigActivity.class);
|
||||
startActivity(i);
|
||||
} else
|
||||
showCategory(entry);
|
||||
}
|
||||
|
||||
private void showCategory(int category) {
|
||||
int file;
|
||||
switch (category) {
|
||||
case CAT_ADDRESSBOOK:
|
||||
file = R.raw.help_addressbook;
|
||||
break;
|
||||
|
||||
case CAT_I2PTUNNEL:
|
||||
file = R.raw.help_i2ptunnel;
|
||||
break;
|
||||
|
||||
case CAT_MAIN:
|
||||
default:
|
||||
file = R.raw.help_main;
|
||||
break;
|
||||
}
|
||||
HelpHtmlFragment f = HelpHtmlFragment.newInstance(file);
|
||||
if (mTwoPane) {
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.detail_fragment, f).commit();
|
||||
} else {
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.main_fragment, f)
|
||||
.addToBackStack("help" + category)
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
36
app/src/main/java/net/i2p/android/help/HelpHtmlFragment.java
Normal file
@ -0,0 +1,36 @@
|
||||
package net.i2p.android.help;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ScrollView;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
|
||||
import org.sufficientlysecure.htmltextview.HtmlTextView;
|
||||
|
||||
public class HelpHtmlFragment extends Fragment {
|
||||
public static final String ARG_HTML_FILE = "htmlFile";
|
||||
|
||||
static HelpHtmlFragment newInstance(int htmlFile) {
|
||||
HelpHtmlFragment f = new HelpHtmlFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ARG_HTML_FILE, htmlFile);
|
||||
f.setArguments(args);
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
ScrollView scroller = new ScrollView(getActivity());
|
||||
HtmlTextView text = new HtmlTextView(getActivity());
|
||||
scroller.addView(text);
|
||||
int padH = getResources().getDimensionPixelOffset(R.dimen.activity_horizontal_margin);
|
||||
int padV = getResources().getDimensionPixelOffset(R.dimen.activity_vertical_margin);
|
||||
text.setPadding(padH, padV, padH, padV);
|
||||
text.setHtmlFromRawResource(getActivity(), getArguments().getInt(ARG_HTML_FILE), true);
|
||||
return scroller;
|
||||
}
|
||||
}
|
47
app/src/main/java/net/i2p/android/help/HelpListFragment.java
Normal file
@ -0,0 +1,47 @@
|
||||
package net.i2p.android.help;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.ListFragment;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
|
||||
public class HelpListFragment extends ListFragment {
|
||||
OnEntrySelectedListener mEntrySelectedCallback;
|
||||
|
||||
// Container Activity must implement this interface
|
||||
public interface OnEntrySelectedListener {
|
||||
public void onEntrySelected(int entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
|
||||
// This makes sure that the container activity has implemented
|
||||
// the callback interface. If not, it throws an exception
|
||||
try {
|
||||
mEntrySelectedCallback = (OnEntrySelectedListener) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString()
|
||||
+ " must implement OnEntrySelectedListener");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
setListAdapter(ArrayAdapter.createFromResource(getActivity(),
|
||||
R.array.help_categories, R.layout.listitem_text));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(ListView parent, View view, int pos, long id) {
|
||||
super.onListItemClick(parent, view, pos, id);
|
||||
mEntrySelectedCallback.onEntrySelected(pos);
|
||||
}
|
||||
}
|
@ -96,11 +96,14 @@ public class TunnelDetailFragment extends Fragment {
|
||||
TextView description = (TextView) v.findViewById(R.id.tunnel_description);
|
||||
description.setText(mTunnel.getDescription());
|
||||
|
||||
TextView details = (TextView) v.findViewById(R.id.tunnel_details);
|
||||
details.setText(mTunnel.getDetails());
|
||||
|
||||
TextView targetIfacePort = (TextView) v.findViewById(R.id.tunnel_target_interface_port);
|
||||
targetIfacePort.setText(mTunnel.getIfacePort());
|
||||
targetIfacePort.setText(mTunnel.getTunnelLink(false));
|
||||
|
||||
TextView accessIfacePort = (TextView) v.findViewById(R.id.tunnel_access_interface_port);
|
||||
accessIfacePort.setText(mTunnel.getIfacePort());
|
||||
accessIfacePort.setText(mTunnel.getTunnelLink(false));
|
||||
|
||||
CheckBox autoStart = (CheckBox) v.findViewById(R.id.tunnel_autostart);
|
||||
autoStart.setChecked(mTunnel.startAutomatically());
|
||||
|
@ -90,6 +90,16 @@ public class TunnelEntry {
|
||||
else return NOT_RUNNING;
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
switch (getStatus()) {
|
||||
case STANDBY:
|
||||
case RUNNING:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isClient() {
|
||||
return TunnelUtil.isClient(mController.getType());
|
||||
}
|
||||
@ -100,18 +110,42 @@ public class TunnelEntry {
|
||||
return Boolean.parseBoolean(mController.getSharedClient());
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this to see if it is okay to linkify getClientLink()
|
||||
* @return true if getClientLink() can be linkified, false otherwise.
|
||||
*/
|
||||
public boolean isClientLinkValid() {
|
||||
return ("ircclient".equals(mController.getType())) &&
|
||||
mController.getListenOnInterface() != null &&
|
||||
mController.getListenPort() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return valid host:port only if isClientLinkValid() is true
|
||||
*/
|
||||
public String getClientLink(boolean linkify) {
|
||||
String host = getClientInterface();
|
||||
String port = getClientPort();
|
||||
String link = host + ":" + port;
|
||||
if (linkify) {
|
||||
if ("ircclient".equals(mController.getType()))
|
||||
link = "irc://" + link;
|
||||
}
|
||||
return link;
|
||||
}
|
||||
|
||||
public String getClientInterface() {
|
||||
String rv;
|
||||
if ("streamrclient".equals(mController.getType()))
|
||||
return mController.getTargetHost();
|
||||
rv = mController.getTargetHost();
|
||||
else
|
||||
return mController.getListenOnInterface();
|
||||
rv = mController.getListenOnInterface();
|
||||
return rv != null ? rv : "";
|
||||
}
|
||||
|
||||
public String getClientPort() {
|
||||
String rv = mController.getListenPort();
|
||||
if (rv != null)
|
||||
return rv;
|
||||
return "";
|
||||
return rv != null ? rv : "";
|
||||
}
|
||||
|
||||
public String getClientDestination() {
|
||||
@ -128,10 +162,10 @@ public class TunnelEntry {
|
||||
/* Server tunnel data */
|
||||
|
||||
/**
|
||||
* Call this to see if it is okay to linkify getServerTarget()
|
||||
* @return true if getServerTarget() can be linkified, false otherwise.
|
||||
* Call this to see if it is okay to linkify getServerLink()
|
||||
* @return true if getServerLink() can be linkified, false otherwise.
|
||||
*/
|
||||
public boolean isServerTargetLinkValid() {
|
||||
public boolean isServerLinkValid() {
|
||||
return ("httpserver".equals(mController.getType()) ||
|
||||
"httpbidirserver".equals(mController.getType())) &&
|
||||
mController.getTargetHost() != null &&
|
||||
@ -139,9 +173,9 @@ public class TunnelEntry {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return valid host:port only if isServerTargetLinkValid() is true
|
||||
* @return valid host:port only if isServerLinkValid() is true
|
||||
*/
|
||||
public String getServerTarget() {
|
||||
public String getServerLink(boolean linkify) {
|
||||
String host;
|
||||
if ("streamrserver".equals(getInternalType()))
|
||||
host = mController.getListenOnInterface();
|
||||
@ -152,7 +186,13 @@ public class TunnelEntry {
|
||||
if (port == null) port = "";
|
||||
if (host.indexOf(':') >= 0)
|
||||
host = '[' + host + ']';
|
||||
return host + ":" + port;
|
||||
String link = host + ":" + port;
|
||||
if (linkify) {
|
||||
if ("httpserver".equals(mController.getType()) ||
|
||||
"httpbidirserver".equals(mController.getType()))
|
||||
link = "http://" + link;
|
||||
}
|
||||
return link;
|
||||
}
|
||||
|
||||
public String getDestinationBase64() {
|
||||
@ -183,18 +223,14 @@ public class TunnelEntry {
|
||||
|
||||
/* Other output formats */
|
||||
|
||||
public String getIfacePort() {
|
||||
if (isClient()) {
|
||||
String host;
|
||||
if ("streamrclient".equals(getInternalType()))
|
||||
host = mController.getTargetHost();
|
||||
else
|
||||
host = mController.getListenOnInterface();
|
||||
String port = mController.getListenPort();
|
||||
if (host == null) host = "";
|
||||
if (port == null) port = "";
|
||||
return host + ":" + port;
|
||||
} else return getServerTarget();
|
||||
public boolean isTunnelLinkValid() {
|
||||
if (isClient()) return isClientLinkValid();
|
||||
else return isServerLinkValid();
|
||||
}
|
||||
|
||||
public String getTunnelLink(boolean linkify) {
|
||||
if (isClient()) return getClientLink(linkify);
|
||||
else return getServerLink(linkify);
|
||||
}
|
||||
|
||||
public String getDetails() {
|
||||
@ -209,16 +245,29 @@ public class TunnelEntry {
|
||||
public Drawable getStatusIcon() {
|
||||
switch (getStatus()) {
|
||||
case STANDBY:
|
||||
return mContext.getResources()
|
||||
.getDrawable(R.drawable.ic_schedule_black_24dp);
|
||||
case STARTING:
|
||||
return mContext.getResources()
|
||||
.getDrawable(R.drawable.local_inprogress);
|
||||
case RUNNING:
|
||||
return mContext.getResources()
|
||||
.getDrawable(R.drawable.local_up);
|
||||
case NOT_RUNNING:
|
||||
default:
|
||||
return mContext.getResources()
|
||||
.getDrawable(R.drawable.local_down);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Drawable getStatusBackground() {
|
||||
switch (getStatus()) {
|
||||
case STANDBY:
|
||||
case STARTING:
|
||||
return mContext.getResources()
|
||||
.getDrawable(R.drawable.tunnel_yellow);
|
||||
case RUNNING:
|
||||
return mContext.getResources()
|
||||
.getDrawable(R.drawable.tunnel_green);
|
||||
case NOT_RUNNING:
|
||||
default:
|
||||
return mContext.getResources()
|
||||
.getDrawable(R.drawable.tunnel_red);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package net.i2p.android.i2ptunnel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -11,6 +11,10 @@ import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TunnelEntryAdapter extends ArrayAdapter<TunnelEntry> {
|
||||
private final LayoutInflater mInflater;
|
||||
|
||||
@ -31,22 +35,36 @@ public class TunnelEntryAdapter extends ArrayAdapter<TunnelEntry> {
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
View v = mInflater.inflate(R.layout.listitem_i2ptunnel, parent, false);
|
||||
TunnelEntry tunnel = getItem(position);
|
||||
final TunnelEntry tunnel = getItem(position);
|
||||
|
||||
ImageView status = (ImageView) v.findViewById(R.id.tunnel_status);
|
||||
status.setImageDrawable(tunnel.getStatusIcon());
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
|
||||
status.setBackgroundDrawable(tunnel.getStatusBackground());
|
||||
else
|
||||
status.setBackground(tunnel.getStatusBackground());
|
||||
|
||||
TextView name = (TextView) v.findViewById(R.id.tunnel_name);
|
||||
name.setText(tunnel.getName());
|
||||
|
||||
TextView type = (TextView) v.findViewById(R.id.tunnel_type);
|
||||
type.setText(tunnel.getType());
|
||||
TextView type = (TextView) v.findViewById(R.id.tunnel_description);
|
||||
type.setText(tunnel.getDescription());
|
||||
|
||||
TextView ifacePort = (TextView) v.findViewById(R.id.tunnel_interface_port);
|
||||
ifacePort.setText(tunnel.getIfacePort());
|
||||
ifacePort.setText(tunnel.getTunnelLink(false));
|
||||
|
||||
TextView details = (TextView) v.findViewById(R.id.tunnel_details);
|
||||
details.setText(tunnel.getDetails());
|
||||
|
||||
ImageView status = (ImageView) v.findViewById(R.id.tunnel_status);
|
||||
status.setImageDrawable(tunnel.getStatusIcon());
|
||||
if (tunnel.isRunning() && tunnel.isTunnelLinkValid()) {
|
||||
View open = v.findViewById(R.id.tunnel_open);
|
||||
open.setVisibility(View.VISIBLE);
|
||||
open.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse(tunnel.getTunnelLink(true)));
|
||||
getContext().startActivity(i);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
@ -1,27 +1,32 @@
|
||||
package net.i2p.android.i2ptunnel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.android.help.HelpActivity;
|
||||
import net.i2p.android.i2ptunnel.util.TunnelConfig;
|
||||
import net.i2p.android.router.I2PFragmentBase;
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.I2PFragmentBase.RouterContextProvider;
|
||||
import net.i2p.i2ptunnel.TunnelControllerGroup;
|
||||
import net.i2p.router.RouterContext;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.ListFragment;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ListView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import net.i2p.android.help.HelpActivity;
|
||||
import net.i2p.android.i2ptunnel.util.TunnelConfig;
|
||||
import net.i2p.android.router.I2PFragmentBase;
|
||||
import net.i2p.android.router.I2PFragmentBase.RouterContextProvider;
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.i2ptunnel.TunnelControllerGroup;
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TunnelListFragment extends ListFragment implements
|
||||
I2PFragmentBase.RouterContextUser,
|
||||
LoaderManager.LoaderCallbacks<List<TunnelEntry>> {
|
||||
@ -50,6 +55,8 @@ public class TunnelListFragment extends ListFragment implements
|
||||
private int mActivatedPosition = ListView.INVALID_POSITION;
|
||||
private boolean mActivateOnItemClick = false;
|
||||
|
||||
private ImageButton mNewTunnel;
|
||||
|
||||
// Container Activity must implement this interface
|
||||
public interface OnTunnelSelectedListener {
|
||||
public void onTunnelSelected(int tunnelId);
|
||||
@ -85,6 +92,27 @@ public class TunnelListFragment extends ListFragment implements
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
// Create the list fragment's content view by calling the super method
|
||||
final View listFragmentView = super.onCreateView(inflater, container, savedInstanceState);
|
||||
|
||||
View v = inflater.inflate(R.layout.fragment_list_with_add, container, false);
|
||||
FrameLayout listContainer = (FrameLayout) v.findViewById(R.id.list_container);
|
||||
listContainer.addView(listFragmentView);
|
||||
|
||||
mNewTunnel = (ImageButton) v.findViewById(R.id.promoted_action);
|
||||
mNewTunnel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Intent wi = new Intent(getActivity(), TunnelWizardActivity.class);
|
||||
startActivityForResult(wi, TUNNEL_WIZARD_REQUEST);
|
||||
}
|
||||
});
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
@ -162,7 +190,7 @@ public class TunnelListFragment extends ListFragment implements
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.fragment_i2ptunnel_list_actions, menu);
|
||||
if (getRouterContext() == null) {
|
||||
menu.findItem(R.id.action_add_tunnel).setVisible(false);
|
||||
mNewTunnel.setVisibility(View.GONE);
|
||||
menu.findItem(R.id.action_start_all_tunnels).setVisible(false);
|
||||
menu.findItem(R.id.action_stop_all_tunnels).setVisible(false);
|
||||
menu.findItem(R.id.action_restart_all_tunnels).setVisible(false);
|
||||
@ -174,26 +202,22 @@ public class TunnelListFragment extends ListFragment implements
|
||||
// Handle presses on the action bar items
|
||||
List<String> msgs;
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_add_tunnel:
|
||||
Intent wi = new Intent(getActivity(), TunnelWizardActivity.class);
|
||||
startActivityForResult(wi, TUNNEL_WIZARD_REQUEST);
|
||||
return true;
|
||||
case R.id.action_start_all_tunnels:
|
||||
msgs = mGroup.startAllControllers();
|
||||
break;
|
||||
case R.id.action_stop_all_tunnels:
|
||||
msgs = mGroup.stopAllControllers();
|
||||
break;
|
||||
case R.id.action_restart_all_tunnels:
|
||||
msgs = mGroup.restartAllControllers();
|
||||
break;
|
||||
case R.id.action_i2ptunnel_help:
|
||||
Intent hi = new Intent(getActivity(), HelpActivity.class);
|
||||
hi.putExtra(HelpActivity.CATEGORY, HelpActivity.CAT_I2PTUNNEL);
|
||||
startActivity(hi);
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
case R.id.action_start_all_tunnels:
|
||||
msgs = mGroup.startAllControllers();
|
||||
break;
|
||||
case R.id.action_stop_all_tunnels:
|
||||
msgs = mGroup.stopAllControllers();
|
||||
break;
|
||||
case R.id.action_restart_all_tunnels:
|
||||
msgs = mGroup.restartAllControllers();
|
||||
break;
|
||||
case R.id.action_i2ptunnel_help:
|
||||
Intent hi = new Intent(getActivity(), HelpActivity.class);
|
||||
hi.putExtra(HelpActivity.CATEGORY, HelpActivity.CAT_I2PTUNNEL);
|
||||
startActivity(hi);
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
// TODO: Do something with the other messages
|
||||
if (msgs.size() > 0)
|
||||
@ -251,7 +275,7 @@ public class TunnelListFragment extends ListFragment implements
|
||||
}
|
||||
|
||||
public void onLoadFinished(Loader<List<TunnelEntry>> loader,
|
||||
List<TunnelEntry> data) {
|
||||
List<TunnelEntry> data) {
|
||||
if (loader.getId() == (mClientTunnels ?
|
||||
CLIENT_LOADER_ID : SERVER_LOADER_ID)) {
|
||||
mAdapter.setData(data);
|
||||
|
@ -174,8 +174,10 @@ public abstract class I2PActivityBase extends ActionBarActivity implements
|
||||
private void selectItem(int pos) {
|
||||
switch (pos) {
|
||||
case 1:
|
||||
Intent news = new Intent(I2PActivityBase.this, NewsActivity.class);
|
||||
startActivity(news);
|
||||
if (!(this instanceof NewsActivity)) {
|
||||
Intent news = new Intent(I2PActivityBase.this, NewsActivity.class);
|
||||
startActivity(news);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
Intent ab = new Intent(I2PActivityBase.this, AddressbookActivity.class);
|
||||
@ -186,8 +188,10 @@ public abstract class I2PActivityBase extends ActionBarActivity implements
|
||||
startActivity(itb);
|
||||
break;
|
||||
case 4:
|
||||
Intent log = new Intent(I2PActivityBase.this, LogActivity.class);
|
||||
startActivity(log);
|
||||
if (!(this instanceof LogActivity)) {
|
||||
Intent log = new Intent(I2PActivityBase.this, LogActivity.class);
|
||||
startActivity(log);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
Intent wp = new Intent(I2PActivityBase.this, WebActivity.class);
|
||||
@ -195,16 +199,20 @@ public abstract class I2PActivityBase extends ActionBarActivity implements
|
||||
startActivity(wp);
|
||||
break;
|
||||
case 6:
|
||||
Intent active = new Intent(I2PActivityBase.this, RateGraphActivity.class);
|
||||
startActivity(active);
|
||||
if (!(this instanceof RateGraphActivity)) {
|
||||
Intent active = new Intent(I2PActivityBase.this, RateGraphActivity.class);
|
||||
startActivity(active);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
Intent peers = new Intent(I2PActivityBase.this, PeersActivity.class);
|
||||
startActivity(peers);
|
||||
break;
|
||||
case 8:
|
||||
Intent netdb = new Intent(I2PActivityBase.this, NetDbActivity.class);
|
||||
startActivity(netdb);
|
||||
if (!(this instanceof NetDbActivity)) {
|
||||
Intent netdb = new Intent(I2PActivityBase.this, NetDbActivity.class);
|
||||
startActivity(netdb);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Intent main = new Intent(I2PActivityBase.this, MainActivity.class);
|
||||
@ -318,8 +326,11 @@ public abstract class I2PActivityBase extends ActionBarActivity implements
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
// The action bar home/up action should open or close the drawer.
|
||||
// ActionBarDrawerToggle will take care of this.
|
||||
if (mDrawerToggle.onOptionsItemSelected(item)) {
|
||||
if (mDrawerToggle.onOptionsItemSelected(item))
|
||||
return true;
|
||||
else if (item.getItemId() == android.R.id.home) {
|
||||
// This happens when mDrawerToggle.setDrawerIndicatorEnabled(false)
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
// Handle action buttons and overflow
|
||||
|
@ -144,7 +144,6 @@ public class MainActivity extends I2PActivityBase implements
|
||||
|
||||
case R.id.menu_help:
|
||||
Intent hi = new Intent(MainActivity.this, HelpActivity.class);
|
||||
hi.putExtra(HelpActivity.CATEGORY, HelpActivity.CAT_MAIN);
|
||||
startActivity(hi);
|
||||
return true;
|
||||
|
||||
|
@ -9,6 +9,10 @@ import android.preference.PreferenceActivity;
|
||||
import android.preference.PreferenceCategory;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
@ -33,6 +37,8 @@ public class SettingsActivity extends PreferenceActivity {
|
||||
private static final String ACTION_PREFS_LOGGING = "net.i2p.android.router.PREFS_LOGGING";
|
||||
private static final String ACTION_PREFS_ADVANCED = "net.i2p.android.router.PREFS_ADVANCED";
|
||||
|
||||
private Toolbar mToolbar;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -55,6 +61,8 @@ public class SettingsActivity extends PreferenceActivity {
|
||||
// Load the legacy preferences headers
|
||||
addPreferencesFromResource(R.xml.settings_headers_legacy);
|
||||
}
|
||||
|
||||
mToolbar.setTitle(getTitle());
|
||||
}
|
||||
|
||||
protected static void setupGraphSettings(Context context, PreferenceScreen ps, RouterContext ctx) {
|
||||
@ -155,6 +163,27 @@ public class SettingsActivity extends PreferenceActivity {
|
||||
loadHeadersFromResource(R.xml.settings_headers, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentView(int layoutResID) {
|
||||
ViewGroup contentView = (ViewGroup) LayoutInflater.from(this).inflate(
|
||||
R.layout.activity_settings,
|
||||
(ViewGroup) getWindow().getDecorView().getRootView(), false);
|
||||
|
||||
mToolbar = (Toolbar) contentView.findViewById(R.id.main_toolbar);
|
||||
mToolbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp));
|
||||
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onBackPressed();
|
||||
}
|
||||
});
|
||||
|
||||
ViewGroup contentWrapper = (ViewGroup) contentView.findViewById(R.id.content_wrapper);
|
||||
LayoutInflater.from(this).inflate(layoutResID, contentWrapper, true);
|
||||
|
||||
getWindow().setContentView(contentView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
List<Properties> lProps = Util.getPropertiesFromPreferences(this);
|
||||
|
@ -14,7 +14,7 @@ public class AddressEntryAdapter extends ArrayAdapter<AddressEntry> {
|
||||
private final LayoutInflater mInflater;
|
||||
|
||||
public AddressEntryAdapter(Context context) {
|
||||
super(context, R.layout.addressbook_list_item);
|
||||
super(context, R.layout.listitem_text);
|
||||
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ public class AddressEntryAdapter extends ArrayAdapter<AddressEntry> {
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
View v = mInflater.inflate(R.layout.addressbook_list_item, parent, false);
|
||||
View v = mInflater.inflate(R.layout.listitem_text, parent, false);
|
||||
AddressEntry address = getItem(position);
|
||||
|
||||
TextView text = (TextView) v.findViewById(R.id.text);
|
||||
|
@ -18,8 +18,6 @@ import android.widget.Spinner;
|
||||
|
||||
import net.i2p.android.router.I2PActivityBase;
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.web.WebActivity;
|
||||
import net.i2p.android.router.web.WebFragment;
|
||||
|
||||
public class AddressbookActivity extends I2PActivityBase
|
||||
implements AddressbookFragment.OnAddressSelectedListener,
|
||||
@ -37,7 +35,7 @@ public class AddressbookActivity extends I2PActivityBase
|
||||
|
||||
@Override
|
||||
protected boolean canUseTwoPanes() {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -114,12 +112,8 @@ public class AddressbookActivity extends I2PActivityBase
|
||||
setResult(Activity.RESULT_OK, result);
|
||||
finish();
|
||||
} else {
|
||||
//Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
//i.setData(Uri.parse("http://" + host));
|
||||
// XXX: Temporarily reverting to inbuilt browser
|
||||
// until an alternative browser is ready.
|
||||
Intent i = new Intent(this, WebActivity.class);
|
||||
i.putExtra(WebFragment.HTML_URI, "http://" + host + '/');
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("http://" + host));
|
||||
startActivity(i);
|
||||
}
|
||||
}
|
||||
|
@ -7,25 +7,29 @@ import android.support.v4.app.ListFragment;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.addressbook.Daemon;
|
||||
import net.i2p.android.help.HelpActivity;
|
||||
import net.i2p.android.router.I2PFragmentBase;
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.I2PFragmentBase.RouterContextProvider;
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.util.NamingServiceUtil;
|
||||
import net.i2p.client.naming.NamingService;
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AddressbookFragment extends ListFragment implements
|
||||
I2PFragmentBase.RouterContextUser,
|
||||
LoaderManager.LoaderCallbacks<List<AddressEntry>> {
|
||||
@ -46,6 +50,8 @@ public class AddressbookFragment extends ListFragment implements
|
||||
private String mBook;
|
||||
private String mCurFilter;
|
||||
|
||||
private ImageButton mAddToAddressbook;
|
||||
|
||||
// Set in onActivityResult()
|
||||
private Intent mAddWizardData;
|
||||
|
||||
@ -84,6 +90,27 @@ public class AddressbookFragment extends ListFragment implements
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
// Create the list fragment's content view by calling the super method
|
||||
final View listFragmentView = super.onCreateView(inflater, container, savedInstanceState);
|
||||
|
||||
View v = inflater.inflate(R.layout.fragment_list_with_add, container, false);
|
||||
FrameLayout listContainer = (FrameLayout) v.findViewById(R.id.list_container);
|
||||
listContainer.addView(listFragmentView);
|
||||
|
||||
mAddToAddressbook = (ImageButton) v.findViewById(R.id.promoted_action);
|
||||
mAddToAddressbook.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Intent wi = new Intent(getActivity(), AddressbookAddWizardActivity.class);
|
||||
startActivityForResult(wi, ADD_WIZARD_REQUEST);
|
||||
}
|
||||
});
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
@ -111,8 +138,8 @@ public class AddressbookFragment extends ListFragment implements
|
||||
// Show actions
|
||||
if (mSearchAddressbook != null)
|
||||
mSearchAddressbook.setVisible(true);
|
||||
if (mAddToAddressbook != null)
|
||||
mAddToAddressbook.setVisible(false);
|
||||
if (mAddToAddressbook != null && mAddToAddressbook.getVisibility() != View.VISIBLE)
|
||||
mAddToAddressbook.setVisibility(View.VISIBLE);
|
||||
|
||||
if (mAddWizardData != null) {
|
||||
// Save the new entry
|
||||
@ -140,24 +167,22 @@ public class AddressbookFragment extends ListFragment implements
|
||||
}
|
||||
|
||||
private MenuItem mSearchAddressbook;
|
||||
private MenuItem mAddToAddressbook;
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.fragment_addressbook_actions, menu);
|
||||
|
||||
mSearchAddressbook = menu.findItem(R.id.action_search_addressbook);
|
||||
mAddToAddressbook = menu.findItem(R.id.action_add_to_addressbook);
|
||||
|
||||
// Hide until needed
|
||||
if (getRouterContext() == null) {
|
||||
mSearchAddressbook.setVisible(false);
|
||||
mAddToAddressbook.setVisible(false);
|
||||
mAddToAddressbook.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// Only allow adding to private book
|
||||
if (!PRIVATE_BOOK.equals(mBook)) {
|
||||
mAddToAddressbook.setVisible(false);
|
||||
mAddToAddressbook.setVisibility(View.GONE);
|
||||
mAddToAddressbook = null;
|
||||
}
|
||||
}
|
||||
@ -167,26 +192,22 @@ public class AddressbookFragment extends ListFragment implements
|
||||
// Handle presses on the action bar items
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_add_to_addressbook:
|
||||
Intent wi = new Intent(getActivity(), AddressbookAddWizardActivity.class);
|
||||
startActivityForResult(wi, ADD_WIZARD_REQUEST);
|
||||
return true;
|
||||
case R.id.action_reload_subscriptions:
|
||||
Daemon.wakeup();
|
||||
Toast.makeText(getActivity(), "Reloading subscriptions...",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
case R.id.action_addressbook_settings:
|
||||
Intent si = new Intent(getActivity(), AddressbookSettingsActivity.class);
|
||||
startActivity(si);
|
||||
return true;
|
||||
case R.id.action_addressbook_help:
|
||||
Intent hi = new Intent(getActivity(), HelpActivity.class);
|
||||
hi.putExtra(HelpActivity.CATEGORY, HelpActivity.CAT_ADDRESSBOOK);
|
||||
startActivity(hi);
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
case R.id.action_reload_subscriptions:
|
||||
Daemon.wakeup();
|
||||
Toast.makeText(getActivity(), "Reloading subscriptions...",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
case R.id.action_addressbook_settings:
|
||||
Intent si = new Intent(getActivity(), AddressbookSettingsActivity.class);
|
||||
startActivity(si);
|
||||
return true;
|
||||
case R.id.action_addressbook_help:
|
||||
Intent hi = new Intent(getActivity(), HelpActivity.class);
|
||||
hi.putExtra(HelpActivity.CATEGORY, HelpActivity.CAT_ADDRESSBOOK);
|
||||
startActivity(hi);
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@ -228,7 +249,7 @@ public class AddressbookFragment extends ListFragment implements
|
||||
}
|
||||
|
||||
public void onLoadFinished(Loader<List<AddressEntry>> loader,
|
||||
List<AddressEntry> data) {
|
||||
List<AddressEntry> data) {
|
||||
if (loader.getId() == (PRIVATE_BOOK.equals(mBook) ?
|
||||
PRIVATE_LOADER_ID : ROUTER_LOADER_ID)) {
|
||||
mAdapter.setData(data);
|
||||
|
@ -1,20 +1,22 @@
|
||||
package net.i2p.android.router.addressbook;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.util.FileUtil;
|
||||
|
||||
public class AddressbookSettingsActivity extends Activity {
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class AddressbookSettingsActivity extends ActionBarActivity {
|
||||
|
||||
private EditText text_content_subscriptions;
|
||||
private Button btn_save_subscriptions;
|
||||
@ -25,6 +27,12 @@ public class AddressbookSettingsActivity extends Activity {
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_addressbook_settings);
|
||||
|
||||
// Set the action bar
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.main_toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
text_content_subscriptions = (EditText) findViewById(R.id.subscriptions_content);
|
||||
btn_save_subscriptions = (Button) findViewById(R.id.button_save_subscriptions);
|
||||
init_actions();
|
||||
@ -32,12 +40,6 @@ public class AddressbookSettingsActivity extends Activity {
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.activity_addressbook_settings, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void init_actions() {
|
||||
btn_save_subscriptions.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View view) {
|
||||
|
@ -11,6 +11,7 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.i2p.android.help.BrowserConfigActivity;
|
||||
import net.i2p.android.help.HelpActivity;
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.util.I2Patterns;
|
||||
@ -26,8 +27,7 @@ public class ConfigureBrowserDialog extends DialogFragment {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
dialogInterface.dismiss();
|
||||
Intent hi = new Intent(getActivity(), HelpActivity.class);
|
||||
hi.putExtra(HelpActivity.CATEGORY, HelpActivity.CAT_CONFIGURE_BROWSER);
|
||||
Intent hi = new Intent(getActivity(), BrowserConfigActivity.class);
|
||||
startActivity(hi);
|
||||
}
|
||||
})
|
||||
|
@ -0,0 +1,125 @@
|
||||
package net.i2p.android.router.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v4.content.AsyncTaskLoader;
|
||||
|
||||
public abstract class BetterAsyncTaskLoader<T> extends AsyncTaskLoader<T> {
|
||||
protected T mData;
|
||||
|
||||
public BetterAsyncTaskLoader(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when there is new data to deliver to the client. The
|
||||
* super class will take care of delivering it; the implementation
|
||||
* here just adds a little more logic.
|
||||
*/
|
||||
@Override
|
||||
public void deliverResult(T data) {
|
||||
if (isReset()) {
|
||||
// An async query came in while the loader is stopped. We
|
||||
// don't need the result.
|
||||
if (data != null) {
|
||||
releaseResources(data);
|
||||
}
|
||||
}
|
||||
|
||||
// Hold a reference to the old data so it doesn't get garbage collected.
|
||||
// We must protect it until the new data has been delivered.
|
||||
T oldData = mData;
|
||||
mData = data;
|
||||
|
||||
if (isStarted()) {
|
||||
// If the Loader is currently started, we can immediately
|
||||
// deliver its results.
|
||||
super.deliverResult(data);
|
||||
}
|
||||
|
||||
// Invalidate the old data as we don't need it any more.
|
||||
if (oldData != null && oldData != data) {
|
||||
releaseResources(oldData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a request to start the Loader.
|
||||
*/
|
||||
@Override
|
||||
protected void onStartLoading() {
|
||||
if (mData != null) {
|
||||
// Deliver any previously loaded data immediately.
|
||||
deliverResult(mData);
|
||||
}
|
||||
|
||||
// Start watching for changes
|
||||
onStartMonitoring();
|
||||
|
||||
if (takeContentChanged() || mData == null) {
|
||||
// When the observer detects a change, it should call onContentChanged()
|
||||
// on the Loader, which will cause the next call to takeContentChanged()
|
||||
// to return true. If this is ever the case (or if the current data is
|
||||
// null), we force a new load.
|
||||
forceLoad();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a request to stop the Loader.
|
||||
*/
|
||||
@Override
|
||||
protected void onStopLoading() {
|
||||
// The Loader is in a stopped state, so we should attempt to cancel the
|
||||
// current load (if there is one).
|
||||
cancelLoad();
|
||||
|
||||
// Note that we leave the observer as is. Loaders in a stopped state
|
||||
// should still monitor the data source for changes so that the Loader
|
||||
// will know to force a new load if it is ever started again.
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a request to completely reset the Loader.
|
||||
*/
|
||||
@Override
|
||||
protected void onReset() {
|
||||
super.onReset();
|
||||
|
||||
// Ensure the loader has been stopped.
|
||||
onStopLoading();
|
||||
|
||||
// At this point we can release the resources associated with 'mData'.
|
||||
if (mData != null) {
|
||||
releaseResources(mData);
|
||||
mData = null;
|
||||
}
|
||||
|
||||
// Stop monitoring for changes.
|
||||
onStopMonitoring();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a request to cancel a load.
|
||||
*/
|
||||
@Override
|
||||
public void onCanceled(T data) {
|
||||
// Attempt to cancel the current asynchronous load.
|
||||
super.onCanceled(data);
|
||||
|
||||
// The load has been canceled, so we should release the resources
|
||||
// associated with 'data'.
|
||||
releaseResources(data);
|
||||
}
|
||||
|
||||
protected abstract void onStartMonitoring();
|
||||
protected abstract void onStopMonitoring();
|
||||
|
||||
/**
|
||||
* Helper function to take care of releasing resources associated
|
||||
* with an actively loaded data set.
|
||||
* For a simple List, there is nothing to do. For something like a Cursor, we
|
||||
* would close it in this method. All resources associated with the Loader
|
||||
* should be released here.
|
||||
*/
|
||||
protected abstract void releaseResources(T data);
|
||||
}
|
BIN
app/src/main/res/drawable-hdpi/ic_arrow_back_white_24dp.png
Normal file
After Width: | Height: | Size: 287 B |
BIN
app/src/main/res/drawable-hdpi/ic_open_in_browser_white_24dp.png
Normal file
After Width: | Height: | Size: 276 B |
BIN
app/src/main/res/drawable-hdpi/ic_schedule_black_24dp.png
Normal file
After Width: | Height: | Size: 650 B |
BIN
app/src/main/res/drawable-hdpi/ic_shop_white_24dp.png
Normal file
After Width: | Height: | Size: 331 B |
BIN
app/src/main/res/drawable-hdpi/ic_stars_white_24dp.png
Normal file
After Width: | Height: | Size: 640 B |
BIN
app/src/main/res/drawable-mdpi/ic_arrow_back_white_24dp.png
Normal file
After Width: | Height: | Size: 240 B |
BIN
app/src/main/res/drawable-mdpi/ic_open_in_browser_white_24dp.png
Normal file
After Width: | Height: | Size: 234 B |
BIN
app/src/main/res/drawable-mdpi/ic_schedule_black_24dp.png
Normal file
After Width: | Height: | Size: 454 B |
BIN
app/src/main/res/drawable-mdpi/ic_shop_white_24dp.png
Normal file
After Width: | Height: | Size: 260 B |
BIN
app/src/main/res/drawable-mdpi/ic_stars_white_24dp.png
Normal file
After Width: | Height: | Size: 444 B |
BIN
app/src/main/res/drawable-xhdpi/ic_arrow_back_white_24dp.png
Normal file
After Width: | Height: | Size: 336 B |
After Width: | Height: | Size: 348 B |
BIN
app/src/main/res/drawable-xhdpi/ic_schedule_black_24dp.png
Normal file
After Width: | Height: | Size: 832 B |
BIN
app/src/main/res/drawable-xhdpi/ic_shop_white_24dp.png
Normal file
After Width: | Height: | Size: 418 B |
BIN
app/src/main/res/drawable-xhdpi/ic_stars_white_24dp.png
Normal file
After Width: | Height: | Size: 793 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_arrow_back_white_24dp.png
Normal file
After Width: | Height: | Size: 410 B |
After Width: | Height: | Size: 480 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_schedule_black_24dp.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
app/src/main/res/drawable-xxhdpi/ic_shop_white_24dp.png
Normal file
After Width: | Height: | Size: 541 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_stars_white_24dp.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/drawable/icon_info_guardianproject_browser.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
app/src/main/res/drawable/icon_org_mozilla_firefox.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
@ -1,48 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:fillViewport="true"
|
||||
android:padding="10px"
|
||||
android:scrollbarStyle="outsideInset"
|
||||
>
|
||||
<LinearLayout
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/main_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView1"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Addressbook Settings"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin"
|
||||
android:layout_marginEnd="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginLeft="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginRight="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginStart="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginTop="@dimen/activity_vertical_margin"
|
||||
android:fillViewport="true"
|
||||
android:scrollbarStyle="outsideInset">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Subscriptions"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/subscriptions_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:inputType="textMultiLine"
|
||||
android:maxLines="@integer/min_lines"
|
||||
android:minLines="@integer/min_lines" >
|
||||
|
||||
<requestFocus />
|
||||
</EditText>
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_save_subscriptions"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Save subscriptions.txt" />
|
||||
android:orientation="vertical">
|
||||
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/textView2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Subscriptions"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
</ScrollView>
|
||||
<EditText
|
||||
android:id="@+id/subscriptions_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:inputType="textMultiLine">
|
||||
|
||||
<requestFocus />
|
||||
</EditText>
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_save_subscriptions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Save subscriptions.txt" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
||||
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/main_fragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</FrameLayout>
|
24
app/src/main/res/layout/activity_help_onepane.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/main_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
app:theme="@style/ThemeOverlay.AppCompat.ActionBar">
|
||||
</android.support.v7.widget.Toolbar>
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/main_fragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
47
app/src/main/res/layout/activity_help_twopane.xml
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/main_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
app:theme="@style/ThemeOverlay.AppCompat.ActionBar">
|
||||
</android.support.v7.widget.Toolbar>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<!--
|
||||
This layout is a two-pane layout for the master/detail
|
||||
flow within a DrawerLayout. See res/values-large/refs.xml
|
||||
and res/values-sw600dp/refs.xml for layout aliases
|
||||
that replace the single-pane version of the layout with
|
||||
this two-pane version.
|
||||
-->
|
||||
|
||||
<!-- The main fragment view -->
|
||||
<FrameLayout
|
||||
android:id="@+id/main_fragment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<!-- The detail fragment view -->
|
||||
<FrameLayout
|
||||
android:id="@+id/detail_fragment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="2" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
21
app/src/main/res/layout/activity_settings.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/main_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/content_wrapper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
</LinearLayout>
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/text"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:padding="6dp"
|
||||
android:textSize="16sp" >
|
||||
</TextView>
|
8
app/src/main/res/layout/fragment_help_browsers.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/browser_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/list_vertical_padding"
|
||||
android:paddingTop="@dimen/list_vertical_padding"
|
||||
android:scrollbars="vertical" />
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tunnel_name"
|
||||
@ -17,16 +17,24 @@
|
||||
android:id="@+id/tunnel_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_below="@+id/tunnel_type"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@+id/tunnel_name"
|
||||
android:text="Tunnel description" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tunnel_details"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@+id/tunnel_description"
|
||||
android:text="Tunnel details" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tunnel_target_interface_port"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_below="@+id/tunnel_description"
|
||||
android:layout_below="@+id/tunnel_type"
|
||||
android:gravity="right"
|
||||
android:text="Interface:port" />
|
||||
|
||||
@ -35,23 +43,15 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@+id/tunnel_name"
|
||||
android:layout_below="@+id/tunnel_details"
|
||||
android:text="@string/i2ptunnel_view_type" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@+id/textView2"
|
||||
android:text="@string/i2ptunnel_view_desc" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tunnel_type"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_below="@+id/tunnel_name"
|
||||
android:layout_below="@+id/tunnel_details"
|
||||
android:text="Tunnel type" />
|
||||
|
||||
<TextView
|
||||
@ -59,7 +59,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@+id/textView1"
|
||||
android:layout_below="@+id/textView2"
|
||||
android:text="@string/i2ptunnel_view_target" />
|
||||
|
||||
<TextView
|
||||
|
24
app/src/main/res/layout/fragment_list_with_add.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/list_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<net.i2p.android.ext.floatingactionbutton.AddFloatingActionButton
|
||||
android:id="@+id/promoted_action"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginBottom="@dimen/listitem_horizontal_margin"
|
||||
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
|
||||
android:layout_marginRight="@dimen/listitem_horizontal_margin"
|
||||
app:fab_colorNormal="@color/accent"
|
||||
app:fab_colorPressed="@color/accent_dark" />
|
||||
</RelativeLayout>
|
@ -2,21 +2,26 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="10dp">
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin"
|
||||
android:layout_marginEnd="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginLeft="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginRight="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginStart="@dimen/activity_horizontal_margin"
|
||||
android:layout_marginTop="@dimen/activity_vertical_margin">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/news_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_above="@+id/news_status"/>
|
||||
android:layout_above="@+id/news_status"
|
||||
android:layout_alignParentTop="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/news_status"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:gravity="end"
|
||||
android:visibility="gone" />
|
||||
</RelativeLayout>
|
||||
|
||||
|
43
app/src/main/res/layout/listitem_browser.xml
Normal file
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/listitem_height_one_line_avatar"
|
||||
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
|
||||
android:layout_marginRight="@dimen/listitem_horizontal_margin">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/browser_icon"
|
||||
android:layout_width="@dimen/listitem_picture_size"
|
||||
android:layout_height="@dimen/listitem_picture_size"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
|
||||
android:layout_marginStart="@dimen/listitem_horizontal_margin"
|
||||
android:scaleType="fitCenter" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/browser_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="@dimen/listitem_text_left_margin"
|
||||
android:layout_marginStart="@dimen/listitem_text_left_margin"
|
||||
android:layout_toLeftOf="@+id/browser_status_icon"
|
||||
android:layout_toStartOf="@+id/browser_status_icon"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Primary" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/browser_status_icon"
|
||||
android:layout_width="@dimen/listitem_picture_size"
|
||||
android:layout_height="@dimen/listitem_picture_size"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="@dimen/listitem_icon_left_margin"
|
||||
android:layout_marginStart="@dimen/listitem_icon_left_margin"
|
||||
android:scaleType="center"
|
||||
android:visibility="gone" />
|
||||
</RelativeLayout>
|
@ -1,49 +1,81 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="5dp" >
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/listitem_height_two_lines"
|
||||
android:paddingEnd="@dimen/listitem_horizontal_margin"
|
||||
android:paddingRight="@dimen/listitem_horizontal_margin">
|
||||
|
||||
<!-- The name of the tunnel -->
|
||||
<TextView android:id="@+id/tunnel_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="3dp"
|
||||
android:textSize="16sp"
|
||||
<!-- Tunnel status -->
|
||||
<ImageView
|
||||
android:id="@+id/tunnel_status"
|
||||
android:layout_width="@dimen/listitem_icon_size"
|
||||
android:layout_height="@dimen/listitem_icon_size"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginRight="5dp"
|
||||
android:text="Tunnel name" />
|
||||
|
||||
<!-- The type of tunnel -->
|
||||
<TextView android:id="@+id/tunnel_type"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/tunnel_name"
|
||||
android:text="Tunnel type" />
|
||||
|
||||
<!-- Additional tunnel details -->
|
||||
<TextView android:id="@+id/tunnel_details"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/tunnel_type"
|
||||
android:text="Tunnel details" />
|
||||
|
||||
<!-- Interface:port the tunnel listens on or points to -->
|
||||
<TextView android:id="@+id/tunnel_interface_port"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toRightOf="@id/tunnel_name"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignTop="@id/tunnel_name"
|
||||
android:gravity="right"
|
||||
android:text="Interface:port" />
|
||||
|
||||
<!-- Status star -->
|
||||
<ImageView android:id="@+id/tunnel_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
|
||||
android:layout_marginStart="@dimen/listitem_horizontal_margin"
|
||||
android:contentDescription="Status" />
|
||||
|
||||
<!-- The name of the tunnel -->
|
||||
<TextView
|
||||
android:id="@+id/tunnel_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginLeft="@dimen/listitem_text_left_margin"
|
||||
android:layout_marginStart="@dimen/listitem_text_left_margin"
|
||||
android:layout_marginTop="@dimen/listitem_text_top_margin_two_lines"
|
||||
android:text="Tunnel name"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Primary" />
|
||||
|
||||
<!-- Open link -->
|
||||
<ImageView
|
||||
android:id="@+id/tunnel_open"
|
||||
android:layout_width="@dimen/listitem_icon_size"
|
||||
android:layout_height="@dimen/listitem_icon_size"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
|
||||
android:layout_marginStart="@dimen/listitem_horizontal_margin"
|
||||
android:contentDescription="Open"
|
||||
android:src="@drawable/ic_open_in_browser_white_24dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<!-- Interface:port the tunnel listens on or points to -->
|
||||
<TextView
|
||||
android:id="@+id/tunnel_interface_port"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@id/tunnel_name"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_toEndOf="@id/tunnel_name"
|
||||
android:layout_toLeftOf="@id/tunnel_open"
|
||||
android:layout_toRightOf="@id/tunnel_name"
|
||||
android:layout_toStartOf="@id/tunnel_open"
|
||||
android:ellipsize="start"
|
||||
android:gravity="right"
|
||||
android:maxLines="1"
|
||||
android:text="Interface:port"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Secondary" />
|
||||
|
||||
<!-- The tunnel description -->
|
||||
<TextView
|
||||
android:id="@+id/tunnel_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@+id/tunnel_name"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignStart="@+id/tunnel_name"
|
||||
android:layout_marginBottom="@dimen/listitem_text_bottom_margin_two_lines"
|
||||
android:layout_toLeftOf="@id/tunnel_open"
|
||||
android:layout_toStartOf="@id/tunnel_open"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="Tunnel description"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Secondary" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
@ -1,24 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="5dp" >
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/listitem_height_two_lines"
|
||||
android:paddingEnd="@dimen/listitem_horizontal_margin"
|
||||
android:paddingRight="@dimen/listitem_horizontal_margin">
|
||||
|
||||
<!-- The nickname of the LeaseSet -->
|
||||
<TextView android:id="@+id/ls_nickname"
|
||||
<TextView
|
||||
android:id="@+id/ls_nickname"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="3dp"
|
||||
android:textSize="16sp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginRight="5dp"
|
||||
android:text="LeaseSet nickname" />
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
|
||||
android:layout_marginStart="@dimen/listitem_horizontal_margin"
|
||||
android:layout_marginTop="@dimen/listitem_text_top_margin_two_lines"
|
||||
android:text="LeaseSet nickname"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Primary" />
|
||||
|
||||
<!-- The hash of the LeaseSet -->
|
||||
<TextView android:id="@+id/dbentry_hash"
|
||||
<TextView
|
||||
android:id="@+id/dbentry_hash"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/ls_nickname"
|
||||
android:text="LeaseSet hash" />
|
||||
android:layout_alignLeft="@+id/ls_nickname"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignStart="@+id/ls_nickname"
|
||||
android:layout_marginBottom="@dimen/listitem_text_bottom_margin_two_lines"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="LeaseSet hash"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Secondary" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
@ -1,25 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="5dp" >
|
||||
|
||||
<!-- The hash of the RouterInfo -->
|
||||
<TextView android:id="@+id/dbentry_hash"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="3dp"
|
||||
android:textSize="16sp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginRight="5dp"
|
||||
android:text="RouterInfo hash" />
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/listitem_height_one_line"
|
||||
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
|
||||
android:layout_marginRight="@dimen/listitem_horizontal_margin">
|
||||
|
||||
<!-- Country flag -->
|
||||
<ImageView android:id="@+id/ri_country"
|
||||
<ImageView
|
||||
android:id="@+id/ri_country"
|
||||
android:layout_width="@dimen/listitem_icon_size"
|
||||
android:layout_height="@dimen/listitem_icon_size"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
|
||||
android:layout_marginStart="@dimen/listitem_horizontal_margin"
|
||||
android:contentDescription="Country"
|
||||
android:visibility="gone" />
|
||||
|
||||
<!-- The hash of the RouterInfo -->
|
||||
<TextView
|
||||
android:id="@+id/dbentry_hash"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="Country" />
|
||||
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
|
||||
android:layout_marginStart="@dimen/listitem_horizontal_margin"
|
||||
android:ellipsize="marquee"
|
||||
android:maxLines="1"
|
||||
android:text="RouterInfo hash"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Primary" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
11
app/src/main/res/layout/listitem_text.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/listitem_height_one_line"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingEnd="@dimen/listitem_horizontal_margin"
|
||||
android:paddingLeft="@dimen/listitem_horizontal_margin"
|
||||
android:paddingRight="@dimen/listitem_horizontal_margin"
|
||||
android:paddingStart="@dimen/listitem_horizontal_margin"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Primary" />
|
@ -1,5 +0,0 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/menu_settings"
|
||||
android:title="@string/menu_settings"
|
||||
android:orderInCategory="100" />
|
||||
</menu>
|
@ -1,11 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:i2pandroid="http://schemas.android.com/apk/res-auto" >
|
||||
<!-- Add, should appear as action buttons -->
|
||||
<item android:id="@+id/action_add_to_addressbook"
|
||||
android:title="@string/action_add"
|
||||
android:icon="@drawable/ic_add_white_24dp"
|
||||
i2pandroid:showAsAction="ifRoom" />
|
||||
<!-- Settings, Help, should always be in the overflow -->
|
||||
<item android:id="@+id/action_reload_subscriptions"
|
||||
android:title="@string/action_reload_subscriptions"
|
||||
|
@ -1,10 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:i2pandroid="http://schemas.android.com/apk/res-auto" >
|
||||
<item android:id="@+id/action_add_tunnel"
|
||||
android:title="@string/action_add"
|
||||
android:icon="@drawable/ic_add_white_24dp"
|
||||
i2pandroid:showAsAction="ifRoom" />
|
||||
<item android:id="@+id/action_start_all_tunnels"
|
||||
android:title="@string/action_i2ptunnel_start_all"
|
||||
i2pandroid:showAsAction="never" />
|
||||
|
@ -1,12 +1,8 @@
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>Pre-configured HTTP proxy</h2>
|
||||
<p>The app starts an HTTP proxy at localhost port 4444. To use it, configure your browser's HTTP proxy setting to use localhost:4444.</p>
|
||||
<p>The HTTP proxy is tested with the "Orweb" app. It should also work with Firefox 4 Mobile and the ProxyMob Firefox plugin, if you have at least 512 MB of RAM.</p>
|
||||
|
||||
<h2>Embedded web browser</h2>
|
||||
<p>An embedded web browser is provided for convenience that will open .i2p addresses. However, it is not recommended for general use; users should download the Orweb browser, or Firefox Mobile and the ProxyMob Firefox plugin.</p>
|
||||
<p>An embedded web browser is provided for convenience that will open .i2p addresses. However, it is not recommended for general use.</p>
|
||||
<p>The browser does not use the outproxy for regular web sites. Javascript is disabled.</p>
|
||||
|
||||
<p>The following problems with eepsites are probably not fixable except on Android 3.0 (Honeycomb - i.e. tablets) and higher due to API limitations. The workaround is to use Firefox Mobile 4 and the ProxMob plugin (see below).</p>
|
@ -1,6 +1,15 @@
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>What is I2PTunnel?</h2>
|
||||
<p>Tunnels are the heart of I2P. All data inside the I2P network is sent through tunnels that hide the location of users. If an app has native I2P support, it will create its own tunnels.</p>
|
||||
<p>I2PTunnel lets you create your own tunnels manually. This is useful for when you want to use an app that doesn't have native I2P support, like:</p>
|
||||
<ul>
|
||||
<li>A browser.</li>
|
||||
<li>An IRC client.</li>
|
||||
<li>A web server.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Using clients with pre-configured tunnels</h2>
|
||||
<p>The app starts an HTTP proxy at localhost port 4444 and IRC client tunnels at localhost ports 6668 - 6672. The IRC clients are "shared clients" on the same tunnels. Once you see the tunnel icon turn green on the main console (several minutes after startup), you should be able to connect.</p>
|
||||
|
||||
@ -8,9 +17,10 @@
|
||||
<ol>
|
||||
<li>Port 6668: IRC2P - irc.postman.i2p, irc.freshcoffee.i2p, and irc.echelon.i2p</li>
|
||||
<li>Port 6669: irc.welterde.i2p</li>
|
||||
<li>Port 6670: irc.telecomix.i2p (probably down)</li>
|
||||
<li>Port 6671: irc.killyourtv.i2p</li>
|
||||
<li>Port 6672: Nameless IRC - irc.stream.i2p</li>
|
||||
<li>Port 6670: irc.killyourtv.i2p</li>
|
||||
</ol>
|
||||
|
||||
<h2>What does the clock icon on a yellow background mean?</h2>
|
||||
<p>When a tunnel's indicator is yellow with a clock icon, the tunnel is in standby mode. This means that I2P has not built the tunnel yet, but will do so automatically when you start using it. This helps to minimize resource use and conserve battery life.</p>
|
||||
</body>
|
||||
</html>
|
11
app/src/main/res/raw/help_info_guardianproject_browser.html
Normal file
@ -0,0 +1,11 @@
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>How to configure Orweb:</h2>
|
||||
<ol>
|
||||
<li>Open Orweb's settings menu.</li>
|
||||
<li>Change the "Proxy Port" to <code>4444</code>.</li>
|
||||
<li>Exit Orweb using the back button, then open it again.</li>
|
||||
</ol>
|
||||
</body>
|
||||
</html>
|
11
app/src/main/res/raw/help_info_guardianproject_orfox.html
Normal file
@ -0,0 +1,11 @@
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>How to configure Orfox:</h2>
|
||||
<ol>
|
||||
<li>Type <code>about:config</code> into the URL bar.</li>
|
||||
<li>Search for <code>network.proxy.http</code>.</li>
|
||||
<li>Change the value of <code>network.proxy.http_port</code> to <code>4444</code>.</li>
|
||||
</ol>
|
||||
</body>
|
||||
</html>
|
@ -7,5 +7,10 @@
|
||||
<h2>How do I use it?</h2>
|
||||
<p>If you want to view I2P sites, see the "Browser configuration" help category.</p>
|
||||
<p>With this app installed, other apps that are designed for I2P will use it automatically.</p>
|
||||
|
||||
<h2>Pre-configured HTTP proxy</h2>
|
||||
<p>The app starts an HTTP proxy at localhost port 4444. To use it, configure your browser's HTTP proxy setting to use localhost:4444.</p>
|
||||
<p>The HTTP proxy is tested with the "Orweb" app. It should also work with Firefox 4 Mobile and the ProxyMob Firefox plugin, if you have at least 512 MB of RAM.</p>
|
||||
<p>See the "Browser configuration" help page for more info.</p>
|
||||
</body>
|
||||
</html>
|
12
app/src/main/res/raw/help_org_mozilla_firefox.html
Normal file
@ -0,0 +1,12 @@
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>How to configure Firefox:</h2>
|
||||
<ol>
|
||||
<li>Type <code>about:config</code> into the URL bar.</li>
|
||||
<li>Search for <code>network.proxy.http</code>.</li>
|
||||
<li>Change the value of <code>network.proxy.http</code> to <code>localhost</code>.</li>
|
||||
<li>Change the value of <code>network.proxy.http_port</code> to <code>4444</code>.</li>
|
||||
</ol>
|
||||
</body>
|
||||
</html>
|
9
app/src/main/res/raw/help_unknown_browser.html
Normal file
@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>This browser is unknown</h2>
|
||||
<p>We have not tested this browser with I2P, so we don't know anything about it.</p>
|
||||
<p>But if this browser supports proxies, it will work with I2P.</p>
|
||||
<p>Configure this browser's HTTP proxy setting to use <code>localhost:4444</code>.</p>
|
||||
</body>
|
||||
</html>
|
7
app/src/main/res/raw/help_unsupported_browser.html
Normal file
@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h2>Sorry, this browser is unsupported</h2>
|
||||
<p>This browser can't be used with I2P.</p>
|
||||
</body>
|
||||
</html>
|
@ -27,7 +27,7 @@ tunnel.0.startOnLoad=true
|
||||
|
||||
# irc
|
||||
tunnel.1.name=Irc2P
|
||||
tunnel.1.description=IRC tunnel to access the Irc2P network
|
||||
tunnel.1.description=IRC tunnel to the Irc2P network
|
||||
tunnel.1.type=ircclient
|
||||
tunnel.1.sharedClient=true
|
||||
tunnel.1.interface=127.0.0.1
|
||||
@ -52,7 +52,7 @@ tunnel.1.startOnLoad=true
|
||||
|
||||
# irc
|
||||
tunnel.2.name=IRC welterde
|
||||
tunnel.2.description=IRC tunnel to access welterde's network
|
||||
tunnel.2.description=IRC tunnel to welterde's network
|
||||
tunnel.2.type=ircclient
|
||||
tunnel.2.sharedClient=true
|
||||
tunnel.2.interface=127.0.0.1
|
||||
@ -73,14 +73,14 @@ tunnel.2.option.outbound.length=2
|
||||
tunnel.2.option.outbound.lengthVariance=0
|
||||
tunnel.2.startOnLoad=true
|
||||
|
||||
# irc
|
||||
tunnel.3.name=Telecomix IRC
|
||||
tunnel.3.description=IRC tunnel to access the Telecomix network
|
||||
# irc irc.killyourtv.i2p
|
||||
tunnel.3.name=KYTV IRC
|
||||
tunnel.3.description=IRC tunnel to KillYourTV's network
|
||||
tunnel.3.type=ircclient
|
||||
tunnel.3.sharedClient=true
|
||||
tunnel.3.interface=127.0.0.1
|
||||
tunnel.3.listenPort=6670
|
||||
tunnel.3.targetDestination=irc.telecomix.i2p
|
||||
tunnel.3.targetDestination=irc.killyourtv.i2p
|
||||
tunnel.3.i2cpHost=127.0.0.1
|
||||
tunnel.3.i2cpPort=7654
|
||||
tunnel.3.option.inbound.nickname=shared clients
|
||||
@ -94,50 +94,4 @@ tunnel.3.option.inbound.length=2
|
||||
tunnel.3.option.inbound.lengthVariance=0
|
||||
tunnel.3.option.outbound.length=2
|
||||
tunnel.3.option.outbound.lengthVariance=0
|
||||
tunnel.3.startOnLoad=true
|
||||
|
||||
# irc irc.killyourtv.i2p
|
||||
tunnel.4.name=KYTV IRC
|
||||
tunnel.4.description=IRC tunnel to access KillYourTV's network
|
||||
tunnel.4.type=ircclient
|
||||
tunnel.4.sharedClient=true
|
||||
tunnel.4.interface=127.0.0.1
|
||||
tunnel.4.listenPort=6671
|
||||
tunnel.4.targetDestination=irc.killyourtv.i2p
|
||||
tunnel.4.i2cpHost=127.0.0.1
|
||||
tunnel.4.i2cpPort=7654
|
||||
tunnel.4.option.inbound.nickname=shared clients
|
||||
tunnel.4.option.outbound.nickname=shared clients
|
||||
tunnel.4.option.i2cp.delayOpen=true
|
||||
tunnel.4.option.i2cp.reduceIdleTime=600000
|
||||
tunnel.4.option.i2cp.reduceOnIdle=true
|
||||
tunnel.4.option.i2cp.reduceQuantity=1
|
||||
tunnel.4.option.i2p.streaming.connectDelay=1000
|
||||
tunnel.4.option.inbound.length=2
|
||||
tunnel.4.option.inbound.lengthVariance=0
|
||||
tunnel.4.option.outbound.length=2
|
||||
tunnel.4.option.outbound.lengthVariance=0
|
||||
tunnel.4.startOnLoad=true
|
||||
|
||||
# irc irc.stream.i2p
|
||||
tunnel.5.name=Nameless IRC
|
||||
tunnel.5.description=IRC tunnel to access the Nameless network
|
||||
tunnel.5.type=ircclient
|
||||
tunnel.5.sharedClient=true
|
||||
tunnel.5.interface=127.0.0.1
|
||||
tunnel.5.listenPort=6672
|
||||
tunnel.5.targetDestination=irc.stream.i2p
|
||||
tunnel.5.i2cpHost=127.0.0.1
|
||||
tunnel.5.i2cpPort=7654
|
||||
tunnel.5.option.inbound.nickname=shared clients
|
||||
tunnel.5.option.outbound.nickname=shared clients
|
||||
tunnel.5.option.i2cp.delayOpen=true
|
||||
tunnel.5.option.i2cp.reduceIdleTime=600000
|
||||
tunnel.5.option.i2cp.reduceOnIdle=true
|
||||
tunnel.5.option.i2cp.reduceQuantity=1
|
||||
tunnel.5.option.i2p.streaming.connectDelay=1000
|
||||
tunnel.5.option.inbound.length=2
|
||||
tunnel.5.option.inbound.lengthVariance=0
|
||||
tunnel.5.option.outbound.length=2
|
||||
tunnel.5.option.outbound.lengthVariance=0
|
||||
tunnel.5.startOnLoad=true
|
||||
tunnel.3.startOnLoad=true
|
@ -1,2 +1 @@
|
||||
irc.welterde.i2p=qv0mnQG0CqKM0b4613~8rOKBLA9ZQLCdU0Iiz6Ou8eszJjvjNCHTaa-Rcorz50~7zMu8Lh~OYplf2JatBhWirTsmbVRlOxtAvqYl0oAfY1bUpUu9AeU9wfgj806jw0vIO6JNDpSiRRhGL6HHYLqDvqvE4JgFFpMjF30dIdBxCGsVa1EbwlUUCpgZV1Psl45l~1wkMJ7NsSglHy46l5m9uYXNxu-NERrMN0~mGxnFsAllJZZCKixFQY-mDDiEMksCF7aNueTm~SknvrVQIue9jVf5lZVvxPSmKuRIEGL3bAC-IF3Jhv0NEhuxAYpzKBT1yMupJficIHhcqwk-iUHNnUqgEH8MRQM4SrrcGeBvwZ-daQVOv~ujLijiFl4QrrNLzArgYOxRZMO1Jz3kAgWxULw3RNiszmIcuxYvGT4z7e5YeuroejyE1ExMis-3JBmbjrd2kOKWX5LqgMeAkDjYIsI8QPigxLbC3l7Y5tbyrZA0t~vvOU--2wP6Kg5rb7r1AAAA
|
||||
irc.telecomix.i2p=ogLZQpnNgs514P0hp-vwPU3iHhKUymyotVxyX7fC8-a4dFAUXx~HUR0ezvkb3RVI3Snvh~yl7QJHzs3hIy2jjZmo~rlZLmtpEVgu1IvrMYusR3KQZ-1Tdfr3JftxA~dr3vmmro3hIhR18xRWA87A~y2VyEGGw4how-EEYS~VT6hnxoJ4FQztvQF0in2A70fCQ1obVYD3lBL~Jn9VV-~tgjohOZHSkIA4yCD80~QfhHa0g4GqJRgQry5fEjAvc1h5owsNyQ8siU3NfldvTd4Tj~dRuD3F91Svk6Wepp~IbPyIKgWPDGWW3RQWFoyDyHjwLI8IdPg0Io8Q4oRgTcA4JJaaHop2WzV7E-thM41h8evo~jO-XDzfW0DFtFTRRK7use5cYLbNlRXVlHQCe7qHALYi3JkH6wBsW5o8irHFMiGYe-YmGEwVRRQ0p2j-tRVJC4jYEOTSTO2Fr~hAUxramtah9wKOd05bSIOYxQxb0~0fGsw3gDMBCZW8PrhFUn3LAAAA
|
||||
|
@ -118,6 +118,7 @@
|
||||
<string name="about_volunteer">Du willst mithelfen, die App besser zu machen? Dann schau in das Android forum:</string>
|
||||
<string name="about_donate">Wenn du Geld oder Bitcoins spenden wilst, damit wir mehr Android-Geräte zum Testen kaufen können, dann schau auf:</string>
|
||||
<string name="menu_help">Hilfe</string>
|
||||
<string name="general">Allgemein</string>
|
||||
<string name="addressbook_search_header">%s gefunden</string>
|
||||
<string name="addressbook_add_wizard_k_name">Name</string>
|
||||
<string name="addressbook_add_wizard_k_destination">Ziel</string>
|
||||
|
@ -118,6 +118,7 @@
|
||||
<string name="about_volunteer">¿Quiere ayudar a hacer mejor la aplicación? Haga de voluntario en el foro de Android:</string>
|
||||
<string name="about_donate">¿Quiere donar dinero o bitcoins para la compra de más dispositivos Android para el desarrollo y testeo? Vaya a:</string>
|
||||
<string name="menu_help">Ayuda</string>
|
||||
<string name="general">General</string>
|
||||
<string name="addressbook_search_header">%s encontrados</string>
|
||||
<string name="addressbook_add_wizard_k_name">Nombre</string>
|
||||
<string name="addressbook_add_wizard_k_destination">Destino</string>
|
||||
|
@ -25,7 +25,9 @@
|
||||
<string name="button_router_off">Presser longtemps pour démarrer I2P</string>
|
||||
<string name="button_router_on">I2P est en marche (presser longtemps pour arrêter)</string>
|
||||
<!--Character to indicate a client tunnel. Usually first letter of the word "client".-->
|
||||
<string name="char_client_tunnel">C</string>
|
||||
<!--Character to indicate a server tunnel. Usually first letter of the word "server".-->
|
||||
<string name="char_server_tunnel">S</string>
|
||||
<string name="no_client_tunnels_running">Aucun tunnel de client n\'est encore en marche.</string>
|
||||
<string name="configure_browser_title">Configurer le navigateur ?</string>
|
||||
<string name="configure_browser_for_i2p">Voudriez-vous configurer un navigateur pour voir les sites d\'I2P ? (vous pouvez aussi faire cela plus tard depuis le menu d\'aide).</string>
|
||||
@ -116,6 +118,7 @@
|
||||
<string name="about_volunteer">Vous souhaitez aider à améliorer l\'application ? Devenez volontaire sur le forum Android :</string>
|
||||
<string name="about_donate">Vous souhaitez faire un don d\'argent ou de bitcoins pour acheter davantage d\'équipements Android pour les développements et les tests ? Allez sur :</string>
|
||||
<string name="menu_help">Aide</string>
|
||||
<string name="general">Général</string>
|
||||
<string name="addressbook_search_header">%s trouvé</string>
|
||||
<string name="addressbook_add_wizard_k_name">Nom</string>
|
||||
<string name="addressbook_add_wizard_k_destination">Destination</string>
|
||||
|
@ -118,6 +118,7 @@
|
||||
<string name="about_volunteer">이 앱을 개선시키고 싶나요? 안드로이드 포럼에서 기여하세요:</string>
|
||||
<string name="about_donate">돈이나 비트코인 기부로 개발과 테스팅에 필요한 안드로이드 기기 구입을 돕고 싶나요? 참조하세요:</string>
|
||||
<string name="menu_help">도움말</string>
|
||||
<string name="general">일반</string>
|
||||
<string name="addressbook_search_header">%s 찾음</string>
|
||||
<string name="addressbook_add_wizard_k_name">이름</string>
|
||||
<string name="addressbook_add_wizard_k_destination">목적지</string>
|
||||
@ -158,6 +159,8 @@
|
||||
<string name="i2ptunnel_wizard_k_outproxies">나가는 프록시</string>
|
||||
<string name="i2ptunnel_wizard_k_target_host">목표 호스트</string>
|
||||
<string name="i2ptunnel_wizard_k_target_port">목표 포트</string>
|
||||
<string name="i2ptunnel_wizard_k_reachable_on">접근가능</string>
|
||||
<string name="i2ptunnel_wizard_k_binding_port">바인드 포트</string>
|
||||
<string name="i2ptunnel_wizard_k_auto_start">자동 시작</string>
|
||||
<string name="next">다음</string>
|
||||
<string name="prev">이전</string>
|
||||
@ -171,6 +174,7 @@
|
||||
<string name="i2ptunnel_wizard_desc_target_host">서비스가 작동중인 IP, 대부분의 경우 같은 기기이기 때문에 127.0.0.1이 자동 입력됨.</string>
|
||||
<string name="i2ptunnel_wizard_desc_target_port">서비스가 접속을 받아들일 포트.</string>
|
||||
<string name="i2ptunnel_wizard_desc_reachable_on">이 터널을 접근할 수 있는 컴퓨터 혹은 스마트폰 제한.</string>
|
||||
<string name="i2ptunnel_wizard_desc_binding_port">이 포트는 로컬에서 접근될 클라이언트 터널입니다. 또한 bidir 서버 터널의 클라이언트 포트이기도 합니다.</string>
|
||||
<string name="i2ptunnel_wizard_desc_auto_start">라우터가 시작할때 터널도 같이 실행?</string>
|
||||
<string name="i2ptunnel_wizard_submit_confirm_message">터널을 만들까요?</string>
|
||||
<string name="i2ptunnel_wizard_submit_confirm_button">터널 </string>
|
||||
|
@ -25,7 +25,12 @@
|
||||
<string name="button_router_off">Hold inne kappen for å starte I2P</string>
|
||||
<string name="button_router_on">I2P kjører (hold inne knappen for å stoppe)</string>
|
||||
<!--Character to indicate a client tunnel. Usually first letter of the word "client".-->
|
||||
<string name="char_client_tunnel">K</string>
|
||||
<!--Character to indicate a server tunnel. Usually first letter of the word "server".-->
|
||||
<string name="char_server_tunnel">T</string>
|
||||
<string name="no_client_tunnels_running">Foreløpig kjører ingen klient-tunneler</string>
|
||||
<string name="configure_browser_title">Sett opp nettleser?</string>
|
||||
<string name="configure_browser_for_i2p">Vil du sette opp nettleseren for visning av I2P-sider? (Du kan også gjøre dette senere fra hjelpemenyen.)</string>
|
||||
<string name="first_start_title">Til lykke med ny installasjon av I2P!</string>
|
||||
<string name="first_start_welcome"><b> Velkommen til I2P</b> Vennligst <b>ha tålmodighet</b> mens I2P starter opp og finner likemenn.</string>
|
||||
<string name="first_start_read">Mens du venter, vennligst les versjons-notatene og velkomstsiden.</string>
|
||||
@ -104,6 +109,7 @@
|
||||
<string name="settings_label_expl_backupQuantity">Sikkerhetskopi-mengde</string>
|
||||
<string name="settings_summ_expl_backupQuantity">%s tunneler</string>
|
||||
<string name="settings_desc_expl_backupQuantity">Hvor mange reservetunneler</string>
|
||||
<string name="settings_router_restart_required">Gjør en omstart av I2P for å utføre endringer</string>
|
||||
<string name="menu_about">Om</string>
|
||||
<string name="about_version">Versjon:</string>
|
||||
<string name="about_project">Prosjekts-heim:</string>
|
||||
@ -112,6 +118,7 @@
|
||||
<string name="about_volunteer">Vil du gjøre dette programmet bedre? Meld deg som frivillig på Android-forumet:</string>
|
||||
<string name="about_donate">Vil du donere penger eller bitcoin øremerket flere Android-enheter til utvikling og testformål? Gå til:</string>
|
||||
<string name="menu_help">Hjelp</string>
|
||||
<string name="general">Generelt</string>
|
||||
<string name="addressbook_search_header">%s funnet</string>
|
||||
<string name="addressbook_add_wizard_k_name">Navn</string>
|
||||
<string name="addressbook_add_wizard_k_destination">Mål-katalog</string>
|
||||
@ -176,4 +183,10 @@
|
||||
<string name="i2ptunnel_view_target">Mål:</string>
|
||||
<string name="i2ptunnel_view_access_point">Tilknytningspunkt:</string>
|
||||
<string name="i2ptunnel_view_autostart">Auto-start</string>
|
||||
<string name="copy_logs">Kopier loggførsel</string>
|
||||
<string name="i2p_android_error_logs">Loggføring av feil for Android I2P</string>
|
||||
<string name="i2p_android_logs">Loggfiler for Android I2P</string>
|
||||
<string name="error_logs_copied_to_clipboard">Utklippstavle for feil-logg</string>
|
||||
<string name="logs_copied_to_clipboard">Utklippstavle for loggføringer</string>
|
||||
<string name="label_browser_configuration">Oppsett av nettleser</string>
|
||||
</resources>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<string name="desc_i2p_logo">Emblema I2P</string>
|
||||
<string name="welcome_new_install">Bine ati venit la I2P! Aceasta aplicatie este un software ALPHA și nu oferă anonimatul puternic. Vă rugăm să citiți notele de lansare și licență.</string>
|
||||
<string name="welcome_new_version">Noua versiune instalată. Vă rugăm să citiți notele de lansare. versiune:</string>
|
||||
<string name="label_home">Stare si Controale</string>
|
||||
<string name="label_home">Controale și stare</string>
|
||||
<string name="label_tunnels">Tuneluri</string>
|
||||
<string name="label_status">Stare</string>
|
||||
<string name="label_addressbook">Agendă</string>
|
||||
@ -25,8 +25,16 @@
|
||||
<string name="button_router_off">Apasari lung pentru a porni I2P</string>
|
||||
<string name="button_router_on">I2P ruleaza (tineti apasat pentru a oprii)</string>
|
||||
<!--Character to indicate a client tunnel. Usually first letter of the word "client".-->
|
||||
<string name="char_client_tunnel">C</string>
|
||||
<!--Character to indicate a server tunnel. Usually first letter of the word "server".-->
|
||||
<string name="char_server_tunnel">S</string>
|
||||
<string name="configure_browser_title">Configurați navigatorul web?</string>
|
||||
<string name="configure_browser_for_i2p">Doriți să configurați un navigator web să vizualizați site-uri I2P? (Puteți face acest lucru mai târziu din meniul ajutor.)</string>
|
||||
<string name="first_start_title">Felicitari pentru instalarea I2P!</string>
|
||||
<string name="first_start_read">Cât timp așteptați, citiți notele de lansare și pagina de bun venit.</string>
|
||||
<string name="first_start_faq_nonanon">Sau utilizați acest link ne-anonim dacă nu doriți să așteptați pentru tuneluri:</string>
|
||||
<string name="drawer_open">Deschide nav</string>
|
||||
<string name="drawer_close">Închide nav</string>
|
||||
<string name="action_search">Cauta</string>
|
||||
<string name="action_add">Adaugă</string>
|
||||
<string name="action_edit">Editeaza</string>
|
||||
@ -47,6 +55,7 @@
|
||||
<string name="graphs_not_ready">Graficele nu sunt gata, sau ruterul nu rulează. Încercați mai târziu.</string>
|
||||
<string name="netdb_routers_empty">Nu sunt rutere în NetDB.</string>
|
||||
<string name="notification_status_bw">Lățime de bandă: %1$s KBps desc / %2$s KBps în</string>
|
||||
<string name="notification_status_peers">Parteneri: %1$d activi, %2$d cunoscuți</string>
|
||||
<string name="menu_settings">Configurări</string>
|
||||
<string name="settings_enable">Activează</string>
|
||||
<string name="settings_desc_subscriptions">URLs de abonare:</string>
|
||||
@ -88,6 +97,7 @@
|
||||
<string name="settings_label_expl_backupQuantity">Cantitatea de rezervă</string>
|
||||
<string name="settings_summ_expl_backupQuantity">%s tuneluri</string>
|
||||
<string name="settings_desc_expl_backupQuantity">Câți copii de rezervă tunel</string>
|
||||
<string name="settings_router_restart_required">Reporniți I2P pentru aplicarea modificărilor</string>
|
||||
<string name="menu_about">Despre</string>
|
||||
<string name="about_version">Versiune:</string>
|
||||
<string name="about_bugs">Defecte și suport:</string>
|
||||
@ -95,16 +105,33 @@
|
||||
<string name="about_volunteer">Doriți să faceți aplicația mai bună? Voluntari pe forumul Android:</string>
|
||||
<string name="about_donate">Doriți să donați bani sau bitcoins pentru cumpărarea de mai multe dispozitive Android pentru dezvoltare și testare? Mergeți la:</string>
|
||||
<string name="menu_help">Ajutor</string>
|
||||
<string name="general">General</string>
|
||||
<string name="addressbook_search_header">%s gasit</string>
|
||||
<string name="addressbook_add_wizard_k_name">Nume</string>
|
||||
<string name="addressbook_add_wizard_k_destination">Destinatie</string>
|
||||
<string name="addressbook_add_wizard_desc_name">Numele</string>
|
||||
<string name="nsu_iae_illegal_char">Numele gazdă \"%1$s\" conține caractere ilegale %2$s</string>
|
||||
<string name="nsu_iae_cannot_start_with">Numele gazdă nu poate începe cu \"%s\"</string>
|
||||
<string name="nsu_iae_cannot_end_with">Numele gazdă nu se poate termina cu \"%s\"</string>
|
||||
<string name="nsu_iae_cannot_contain">Numele gazdă nu poate conține \"%s\"</string>
|
||||
<string name="nsu_iae_requires_conversion">Numele gazdă \"%s\" necesită conversia la ASCII dar biblioteca de conversie nu este disponibilă în versiunea Android</string>
|
||||
<string name="i2ptunnel_type_client">Client standard</string>
|
||||
<string name="i2ptunnel_type_httpclient">Client HTTP</string>
|
||||
<string name="i2ptunnel_type_ircclient">Client IRC</string>
|
||||
<string name="i2ptunnel_type_server">Server standard</string>
|
||||
<string name="i2ptunnel_type_httpserver">HTTP server</string>
|
||||
<string name="i2ptunnel_type_sockstunnel">SOCKS 4/4a/5 proxy</string>
|
||||
<string name="i2ptunnel_type_socksirctunnel">SOCKS IRC proxy</string>
|
||||
<string name="i2ptunnel_type_ircserver">Server IRC</string>
|
||||
<string name="i2ptunnel_new_tunnel">Tunel nou</string>
|
||||
<string name="i2ptunnel_msg_config_saved">Modificările configurării s-au salvat</string>
|
||||
<string name="i2ptunnel_msg_config_save_failed">A eșuat salvarea configurării</string>
|
||||
<string name="i2ptunnel_msg_tunnel_starting">Se pornește tunelul</string>
|
||||
<string name="i2ptunnel_msg_tunnel_stopping">Se oprește tunelul</string>
|
||||
<string name="i2ptunnel_delete_confirm_message">Se șterge tunelul?</string>
|
||||
<string name="i2ptunnel_delete_confirm_button">Șterge tunelul</string>
|
||||
<string name="i2ptunnel_wizard_k_client_server">Client sau server</string>
|
||||
<string name="i2ptunnel_wizard_k_type">Tip tunel</string>
|
||||
<string name="i2ptunnel_wizard_k_name">Nume</string>
|
||||
<string name="i2ptunnel_wizard_k_desc">Descriere</string>
|
||||
<string name="i2ptunnel_wizard_k_dest">Destinatie</string>
|
||||
@ -113,6 +140,12 @@
|
||||
<string name="i2ptunnel_wizard_k_auto_start">Auto pornire</string>
|
||||
<string name="next">Urmatorul</string>
|
||||
<string name="prev">Anteriorul</string>
|
||||
<string name="finish">Trimite</string>
|
||||
<string name="enabled">Activat</string>
|
||||
<string name="i2ptunnel_wizard_desc_name">Numele tunelului, pentru identificare în lista tunelurilor.</string>
|
||||
<string name="i2ptunnel_wizard_desc_desc">O descriere a tunelului. Este facultativ și pur informativ.</string>
|
||||
<string name="i2ptunnel_wizard_desc_reachable_on">Aceasta limitează ce computere sau smartphone-uri pot accesa acest tunel.</string>
|
||||
<string name="i2ptunnel_wizard_desc_auto_start">Ar trebui ca tunelul să pornească automat când ruterul pornește?</string>
|
||||
<string name="i2ptunnel_wizard_submit_confirm_message">Se creează tunelul?</string>
|
||||
<string name="i2ptunnel_wizard_submit_confirm_button">Creare tunel</string>
|
||||
<string name="i2ptunnel_view_type">Tip:</string>
|
||||
@ -120,4 +153,10 @@
|
||||
<string name="i2ptunnel_view_target">Tinta:</string>
|
||||
<string name="i2ptunnel_view_access_point">Punct de acces:</string>
|
||||
<string name="i2ptunnel_view_autostart">Auto pornire</string>
|
||||
<string name="copy_logs">Copiază jurnale</string>
|
||||
<string name="i2p_android_error_logs">Jurnale eroare I2P Android</string>
|
||||
<string name="i2p_android_logs">Jurnale I2P Android</string>
|
||||
<string name="error_logs_copied_to_clipboard">Jurnalele de eroare sunt copiate în memoria temporară</string>
|
||||
<string name="logs_copied_to_clipboard">Jurnalele sunt copiate în memoria temporară</string>
|
||||
<string name="label_browser_configuration">Configurare navigator web</string>
|
||||
</resources>
|
||||
|
@ -118,6 +118,7 @@
|
||||
<string name="about_volunteer">Хотите помочь улучшить приложение? Добровольцы на Android форуме:</string>
|
||||
<string name="about_donate">Хотите пожертвовать деньги или bitcoins на покупку дополнительных Android устройств для разработчиков и тестировщиков? Зайдите:</string>
|
||||
<string name="menu_help">Справка</string>
|
||||
<string name="general">Общие</string>
|
||||
<string name="addressbook_search_header">%s найдено</string>
|
||||
<string name="addressbook_add_wizard_k_name">Имя</string>
|
||||
<string name="addressbook_add_wizard_k_destination">Пункт назначения</string>
|
||||
|
@ -1,4 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<item name="activity_navdrawer" type="layout">@layout/activity_navdrawer_twopane</item>
|
||||
<item name="activity_help" type="layout">@layout/activity_help_twopane</item>
|
||||
</resources>
|
||||
|
@ -118,6 +118,7 @@
|
||||
<string name="about_volunteer">想帮助让应用程序变得更好吗?成为Android 论坛志愿者:</string>
|
||||
<string name="about_donate">想捐钱或比特币来为开发和测试购买更多Android 设备吗?转到:</string>
|
||||
<string name="menu_help">帮助</string>
|
||||
<string name="general">常规</string>
|
||||
<string name="addressbook_search_header">%s 找到</string>
|
||||
<string name="addressbook_add_wizard_k_name">名称</string>
|
||||
<string name="addressbook_add_wizard_k_destination">目的地</string>
|
||||
|
@ -51,9 +51,29 @@
|
||||
<item>2</item>
|
||||
</string-array>
|
||||
<string-array name="help_categories">
|
||||
<item>@string/app_name</item>
|
||||
<item>@string/general</item>
|
||||
<item>@string/label_browser_configuration</item>
|
||||
<item>@string/label_addressbook</item>
|
||||
<item>@string/label_i2ptunnel</item>
|
||||
</string-array>
|
||||
<string-array name="recommended_browsers">
|
||||
<item>info.guardianproject.browser</item>
|
||||
</string-array>
|
||||
<string-array name="recommended_browser_labels">
|
||||
<item>Orweb</item>
|
||||
</string-array>
|
||||
<string-array name="supported_browsers">
|
||||
<item>org.mozilla.firefox</item>
|
||||
</string-array>
|
||||
<string-array name="supported_browser_labels">
|
||||
<item>Firefox</item>
|
||||
</string-array>
|
||||
<string-array name="unsupported_browsers">
|
||||
<item>com.android.chrome</item>
|
||||
<item>com.android.browser</item>
|
||||
<item>com.sec.android.app.sbrowser</item>
|
||||
<item>acr.browser.lightning</item>
|
||||
<item>mobi.mgeek.TunnyBrowser</item>
|
||||
<item>com.lastpass.lpandroid</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
|
@ -1,7 +1,8 @@
|
||||
<resources>
|
||||
<color name="primary">#673ab7</color>
|
||||
<color name="primary_dark">#512da8</color>
|
||||
<color name="accent">#ff6e40</color>
|
||||
<color name="primary">#673ab7</color><!-- Deep Purple 500 -->
|
||||
<color name="primary_dark">#512da8</color><!-- Deep Purple 700 -->
|
||||
<color name="accent">#ff6e40</color><!-- Deep Orange A200 -->
|
||||
<color name="accent_dark">#ff3d00</color><!-- Deep Orange A400 -->
|
||||
|
||||
<color name="indicator_red">#ffff0000</color>
|
||||
<color name="indicator_yellow">#ffffff00</color>
|
||||
|
@ -6,6 +6,23 @@
|
||||
<dimen name="nav_horizontal_margin">16dp</dimen>
|
||||
<dimen name="nav_entry_height">48dp</dimen>
|
||||
|
||||
<dimen name="text_size_primary">16sp</dimen>
|
||||
<dimen name="text_size_secondary">14sp</dimen>
|
||||
|
||||
<dimen name="list_vertical_padding">8dp</dimen>
|
||||
<dimen name="listitem_horizontal_margin">16dp</dimen>
|
||||
<dimen name="listitem_picture_size">40dp</dimen>
|
||||
<dimen name="listitem_icon_size">24dp</dimen>
|
||||
<dimen name="listitem_text_left_margin">72dp</dimen>
|
||||
<dimen name="listitem_icon_left_margin">8dp</dimen>
|
||||
|
||||
<dimen name="listitem_height_one_line">48dp</dimen>
|
||||
<dimen name="listitem_height_one_line_avatar">56dp</dimen>
|
||||
|
||||
<dimen name="listitem_height_two_lines">72dp</dimen>
|
||||
<dimen name="listitem_text_top_margin_two_lines">16dp</dimen>
|
||||
<dimen name="listitem_text_bottom_margin_two_lines">18dp</dimen>
|
||||
|
||||
<dimen name="tunnel_indicator">20dp</dimen>
|
||||
|
||||
<dimen name="step_pager_tab_width">32dp</dimen>
|
||||
|
@ -1,4 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<item name="activity_navdrawer" type="layout">@layout/activity_navdrawer_onepane</item>
|
||||
<item name="activity_help" type="layout">@layout/activity_help_onepane</item>
|
||||
</resources>
|
||||
|
@ -138,6 +138,7 @@
|
||||
<string name="url_donate" translatable="false">https://geti2p.net/en/donate | http://i2p-projekt.i2p/en/donate</string>
|
||||
|
||||
<string name="menu_help">Help</string>
|
||||
<string name="general">General</string>
|
||||
|
||||
<string name="addressbook_search_header">%s found</string>
|
||||
|
||||
|
@ -19,6 +19,16 @@
|
||||
<!-- The rest of your attributes -->
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.AppCompat.Primary" parent="TextAppearance.AppCompat.Body1">
|
||||
<item name="android:textColor">@color/primary_text_default_material_dark</item>
|
||||
<item name="android:textSize">@dimen/text_size_primary</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.AppCompat.Secondary" parent="TextAppearance.AppCompat.Body1">
|
||||
<item name="android:textColor">@color/secondary_text_default_material_dark</item>
|
||||
<item name="android:textSize">@dimen/text_size_secondary</item>
|
||||
</style>
|
||||
|
||||
<style name="WizardPageContainer">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">match_parent</item>
|
||||
|
@ -11,6 +11,7 @@ import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import net.i2p.android.lib.client.R;
|
||||
import net.i2p.android.router.service.IRouterState;
|
||||
@ -26,6 +27,10 @@ public class I2PAndroidHelper {
|
||||
|
||||
public static final int REQUEST_START_I2P = 9857;
|
||||
|
||||
private static final String ROUTER_SERVICE_CLASS = "net.i2p.android.router.service.RouterService";
|
||||
|
||||
private static final String LOG_TAG = "I2PClientLib";
|
||||
|
||||
private Context mContext;
|
||||
private boolean mTriedBindState;
|
||||
private IRouterState mStateService;
|
||||
@ -39,17 +44,69 @@ public class I2PAndroidHelper {
|
||||
* {@link android.app.Activity#onStart()}.
|
||||
*/
|
||||
public void bind() {
|
||||
Intent i2pIntent = new Intent(IRouterState.class.getName());
|
||||
try {
|
||||
mTriedBindState = mContext.bindService(
|
||||
i2pIntent, mStateConnection, Context.BIND_AUTO_CREATE);
|
||||
} catch (SecurityException e) {
|
||||
// Old version of I2P Android (pre-0.9.13), cannot use
|
||||
mStateService = null;
|
||||
mTriedBindState = false;
|
||||
Log.i(LOG_TAG, "Binding to I2P Android");
|
||||
Intent i2pIntent = getI2PAndroidIntent();
|
||||
if (i2pIntent != null) {
|
||||
Log.i(LOG_TAG, i2pIntent.toString());
|
||||
try {
|
||||
mTriedBindState = mContext.bindService(
|
||||
i2pIntent, mStateConnection, Context.BIND_AUTO_CREATE);
|
||||
if (!mTriedBindState)
|
||||
Log.w(LOG_TAG, "Could not bind: bindService failed");
|
||||
} catch (SecurityException e) {
|
||||
// Old version of I2P Android (pre-0.9.13), cannot use
|
||||
mStateService = null;
|
||||
mTriedBindState = false;
|
||||
Log.w(LOG_TAG, "Could not bind: I2P Android version is too old");
|
||||
}
|
||||
} else
|
||||
Log.w(LOG_TAG, "Could not bind: I2P Android not installed");
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to bind to I2P Android, using the provided ServiceConnection and
|
||||
* flags. Call this method from
|
||||
* {@link android.app.Service#onStartCommand(android.content.Intent, int, int)}.
|
||||
* The ServiceConnection will be provided with an {@link android.os.IBinder}
|
||||
* that can be converted to an
|
||||
* {@link net.i2p.android.router.service.IRouterState} with
|
||||
* <code>IRouterState.Stub.asInterface(IBinder)</code>.
|
||||
*/
|
||||
public boolean bind(ServiceConnection serviceConnection, int flags) {
|
||||
Log.i(LOG_TAG, "Binding to I2P Android with provided ServiceConnection");
|
||||
Intent i2pIntent = getI2PAndroidIntent();
|
||||
if (i2pIntent != null) {
|
||||
Log.i(LOG_TAG, i2pIntent.toString());
|
||||
try {
|
||||
boolean rv = mContext.bindService(
|
||||
i2pIntent, serviceConnection, flags);
|
||||
if (!rv)
|
||||
Log.w(LOG_TAG, "Could not bind: bindService failed");
|
||||
return rv;
|
||||
} catch (SecurityException e) {
|
||||
// Old version of I2P Android (pre-0.9.13), cannot use
|
||||
Log.w(LOG_TAG, "Could not bind: I2P Android version is too old");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
Log.w(LOG_TAG, "Could not bind: I2P Android not installed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private Intent getI2PAndroidIntent() {
|
||||
Intent intent = new Intent(IRouterState.class.getName());
|
||||
if (isAppInstalled(URI_I2P_ANDROID))
|
||||
intent.setClassName(URI_I2P_ANDROID, ROUTER_SERVICE_CLASS);
|
||||
else if (isAppInstalled(URI_I2P_ANDROID_DONATE))
|
||||
intent.setClassName(URI_I2P_ANDROID_DONATE, ROUTER_SERVICE_CLASS);
|
||||
else if (isAppInstalled(URI_I2P_ANDROID_LEGACY))
|
||||
intent.setClassName(URI_I2P_ANDROID_LEGACY, ROUTER_SERVICE_CLASS);
|
||||
else
|
||||
intent = null;
|
||||
return intent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unbind from I2P Android. Call this method from
|
||||
* {@link android.app.Activity#onStop()}.
|
||||
@ -75,6 +132,7 @@ public class I2PAndroidHelper {
|
||||
|
||||
/**
|
||||
* Check if I2P Android is installed.
|
||||
*
|
||||
* @return true if I2P Android is installed, false otherwise.
|
||||
*/
|
||||
public boolean isI2PAndroidInstalled() {
|
||||
@ -97,6 +155,7 @@ public class I2PAndroidHelper {
|
||||
|
||||
/**
|
||||
* Show dialog - install I2P Android from market or F-Droid.
|
||||
*
|
||||
* @param activity the Activity this method has been called from.
|
||||
*/
|
||||
public void promptToInstall(final Activity activity) {
|
||||
@ -121,6 +180,7 @@ public class I2PAndroidHelper {
|
||||
/**
|
||||
* Check if I2P Android is running. If {@link net.i2p.android.ui.I2PAndroidHelper#bind()}
|
||||
* has not been called previously, this will always return false.
|
||||
*
|
||||
* @return true if I2P Android is running, false otherwise.
|
||||
*/
|
||||
public boolean isI2PAndroidRunning() {
|
||||
@ -137,6 +197,7 @@ public class I2PAndroidHelper {
|
||||
|
||||
/**
|
||||
* Show dialog - request that I2P Android be started.
|
||||
*
|
||||
* @param activity the Activity this method has been called from.
|
||||
*/
|
||||
public void requestI2PAndroidStart(final Activity activity) {
|
||||
|
9
client/src/main/res/values-ko/strings.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<string name="yes">네</string>
|
||||
<string name="no">아니요</string>
|
||||
<string name="install_i2p_android">안드로이드 I2P를 설치할까요?</string>
|
||||
<string name="you_must_have_i2p_android">안드로이드 I2P가 설치되고 작동 되어야 합니다. 설치하시겠습니까?</string>
|
||||
<string name="start_i2p_android">안드로이드 I2P를 시작할까요?</string>
|
||||
<string name="would_you_like_to_start_i2p_android">안드로이드 I2P가 작동중이 아닌것 같습니다. 시작할까요?</string>
|
||||
</resources>
|
9
client/src/main/res/values-ro/strings.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<string name="yes">Da</string>
|
||||
<string name="no">Nu</string>
|
||||
<string name="install_i2p_android">Instalați I2P Android?</string>
|
||||
<string name="you_must_have_i2p_android">Trebuie să aveți instalat și să ruleze I2P Android. Doriți să îl instalați?</string>
|
||||
<string name="start_i2p_android">Porniți I2P Android?</string>
|
||||
<string name="would_you_like_to_start_i2p_android">Apare că I2P Android nu rulează. Doriți să îl porniți?</string>
|
||||
</resources>
|
@ -1,4 +1,4 @@
|
||||
VERSION_NAME=0.3
|
||||
VERSION_NAME=0.4
|
||||
GROUP=net.i2p.android
|
||||
|
||||
POM_URL=https://github.com/i2p/i2p.android.base
|
||||
|
@ -32,11 +32,11 @@ def getSnapshotRepositoryUrl() {
|
||||
}
|
||||
|
||||
def getRepositoryUsername() {
|
||||
return hasProperty('ossrhUsername') ? ossrhUsername : ""
|
||||
return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : ""
|
||||
}
|
||||
|
||||
def getRepositoryPassword() {
|
||||
return hasProperty('ossrhPassword') ? ossrhPassword : ""
|
||||
return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : ""
|
||||
}
|
||||
|
||||
afterEvaluate { project ->
|
||||
|