mirror of
https://github.com/M66B/NetGuard.git
synced 2025-03-15 16:29:42 +00:00
Proper lifetime management, added menu, layout improvements
This commit is contained in:
parent
2f3e8f4e3f
commit
310872f432
15 changed files with 255 additions and 121 deletions
2
.idea/vcs.xml
generated
2
.idea/vcs.xml
generated
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="" />
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -11,7 +11,9 @@
|
|||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".ActivityMain">
|
||||
<activity
|
||||
android:name=".ActivityMain"
|
||||
android:launchMode="singleTop">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package eu.faircode.netguard;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.VpnService;
|
||||
|
@ -10,25 +11,34 @@ import android.os.Bundle;
|
|||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ActivityMain extends AppCompatActivity {
|
||||
public class ActivityMain extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
private static final String TAG = "NetGuard.Main";
|
||||
private static final int REQUEST_VPN = 1;
|
||||
|
||||
private boolean running = false;
|
||||
private RuleAdapter adapter = null;
|
||||
|
||||
private static final int REQUEST_VPN = 1;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
Log.i(TAG, "Create");
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
|
||||
running = true;
|
||||
|
||||
// Action bar
|
||||
View view = getLayoutInflater().inflate(R.layout.actionbar, null);
|
||||
getSupportActionBar().setDisplayShowCustomEnabled(true);
|
||||
getSupportActionBar().setCustomView(view);
|
||||
|
@ -39,8 +49,6 @@ public class ActivityMain extends AppCompatActivity {
|
|||
Switch swEnabled = (Switch) view.findViewById(R.id.swEnabled);
|
||||
swEnabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
prefs.edit().putBoolean("enabled", isChecked).apply();
|
||||
|
||||
if (isChecked) {
|
||||
Log.i(TAG, "On");
|
||||
Intent intent = VpnService.prepare(ActivityMain.this);
|
||||
|
@ -53,15 +61,18 @@ public class ActivityMain extends AppCompatActivity {
|
|||
}
|
||||
} else {
|
||||
Log.i(TAG, "Off");
|
||||
prefs.edit().putBoolean("enabled", false).apply();
|
||||
Intent intent = new Intent(ActivityMain.this, BlackHoleService.class);
|
||||
intent.putExtra(BlackHoleService.EXTRA_START, false);
|
||||
Log.i(TAG, "Stop service=" + intent);
|
||||
intent.putExtra(BlackHoleService.EXTRA_COMMAND, BlackHoleService.Command.stop);
|
||||
startService(intent);
|
||||
}
|
||||
}
|
||||
});
|
||||
swEnabled.setChecked(prefs.getBoolean("enabled", false));
|
||||
|
||||
// Listen for external enabled changes
|
||||
prefs.registerOnSharedPreferenceChangeListener(this);
|
||||
|
||||
// Package list
|
||||
final RecyclerView rvApplication = (RecyclerView) findViewById(R.id.rvApplication);
|
||||
rvApplication.setHasFixedSize(true);
|
||||
|
@ -83,19 +94,70 @@ public class ActivityMain extends AppCompatActivity {
|
|||
}.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences prefs, String name) {
|
||||
Log.i(TAG, "Changed pref=" + name);
|
||||
if ("enabled".equals(name)) {
|
||||
boolean enabled = prefs.getBoolean(name, false);
|
||||
Switch swEnabled = (Switch) getSupportActionBar().getCustomView().findViewById(R.id.swEnabled);
|
||||
if (swEnabled.isChecked() != enabled)
|
||||
swEnabled.setChecked(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
Log.i(TAG, "Destroy");
|
||||
running = false;
|
||||
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.main, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
// Handle item selection
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_vpn_settings:
|
||||
Intent intent = new Intent("android.net.vpn.SETTINGS");
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
if (intent.resolveActivity(getPackageManager()) != null)
|
||||
startActivity(intent);
|
||||
else
|
||||
Log.w(TAG, intent + " not available");
|
||||
return true;
|
||||
|
||||
case R.id.menu_about:
|
||||
LayoutInflater inflater = LayoutInflater.from(this);
|
||||
View view = inflater.inflate(R.layout.about, null);
|
||||
TextView tvVersion = (TextView) view.findViewById(R.id.tvVersion);
|
||||
tvVersion.setText(Util.getSelfVersionName(this));
|
||||
AlertDialog dialog = new AlertDialog.Builder(this)
|
||||
.setView(view)
|
||||
.setCancelable(true).create();
|
||||
dialog.show();
|
||||
return true;
|
||||
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == REQUEST_VPN) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
prefs.edit().putBoolean("enabled", resultCode == RESULT_OK).apply();
|
||||
|
||||
if (resultCode == RESULT_OK) {
|
||||
Intent intent = new Intent(this, BlackHoleService.class);
|
||||
intent.putExtra(BlackHoleService.EXTRA_START, true);
|
||||
Log.i(TAG, "Start service=" + intent);
|
||||
Intent intent = new Intent(ActivityMain.this, BlackHoleService.class);
|
||||
intent.putExtra(BlackHoleService.EXTRA_COMMAND, BlackHoleService.Command.start);
|
||||
startService(intent);
|
||||
}
|
||||
} else
|
||||
|
|
|
@ -5,10 +5,10 @@ import android.content.BroadcastReceiver;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.VpnService;
|
||||
import android.os.IBinder;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
@ -19,47 +19,50 @@ import java.io.IOException;
|
|||
public class BlackHoleService extends VpnService implements Runnable {
|
||||
private static final String TAG = "NetGuard.BlackHole";
|
||||
|
||||
private Thread thread;
|
||||
private Thread thread = null;
|
||||
public static final String EXTRA_COMMAND = "Command";
|
||||
|
||||
public static final String EXTRA_START = "Start";
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
public enum Command {start, reload, stop}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
Log.i(TAG, "Start intent=" + intent);
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
boolean enabled = prefs.getBoolean("enabled", false);
|
||||
|
||||
if (thread != null)
|
||||
thread.interrupt();
|
||||
Command cmd = (intent == null ? Command.start : (Command) intent.getSerializableExtra(EXTRA_COMMAND));
|
||||
Log.i(TAG, "Start intent=" + intent + " command=" + cmd + " enabled=" + enabled + " running=" + (thread != null));
|
||||
|
||||
boolean enabled = (intent != null &&
|
||||
intent.hasExtra(EXTRA_START) &&
|
||||
intent.getBooleanExtra(EXTRA_START, false));
|
||||
|
||||
if (enabled) {
|
||||
Log.i(TAG, "Starting");
|
||||
thread = new Thread(this, "BlackHoleThread");
|
||||
thread.start();
|
||||
if (cmd == Command.reload || cmd == Command.stop) {
|
||||
if (thread != null) {
|
||||
Log.i(TAG, "Stopping");
|
||||
thread.interrupt();
|
||||
}
|
||||
if (cmd == Command.stop)
|
||||
stopSelf();
|
||||
}
|
||||
|
||||
if (cmd == Command.start || cmd == Command.reload) {
|
||||
if (enabled && (thread == null || thread.isInterrupted())) {
|
||||
Log.i(TAG, "Starting");
|
||||
thread = new Thread(this, "BlackHoleThread");
|
||||
thread.start();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check if start sticky is enough to keep the VPN service alive
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
private BroadcastReceiver connectivityChangedReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("enabled", false))
|
||||
if (intent.hasExtra(ConnectivityManager.EXTRA_NETWORK_TYPE) &&
|
||||
intent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, ConnectivityManager.TYPE_DUMMY) == ConnectivityManager.TYPE_WIFI) {
|
||||
Intent service = new Intent(BlackHoleService.this, BlackHoleService.class);
|
||||
service.putExtra(BlackHoleService.EXTRA_START, true);
|
||||
Log.i(TAG, "Start service=" + service);
|
||||
startService(service);
|
||||
}
|
||||
Log.i(TAG, "Received " + intent);
|
||||
Util.logExtras(TAG, intent);
|
||||
if (intent.hasExtra(ConnectivityManager.EXTRA_NETWORK_TYPE) &&
|
||||
intent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, ConnectivityManager.TYPE_DUMMY) == ConnectivityManager.TYPE_WIFI) {
|
||||
Intent service = new Intent(BlackHoleService.this, BlackHoleService.class);
|
||||
service.putExtra(BlackHoleService.EXTRA_COMMAND, Command.reload);
|
||||
startService(service);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -86,11 +89,13 @@ public class BlackHoleService extends VpnService implements Runnable {
|
|||
Log.i(TAG, "Revoke");
|
||||
if (thread != null)
|
||||
thread.interrupt();
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
prefs.edit().putBoolean("enabled", false).apply();
|
||||
super.onRevoke();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
public synchronized void run() {
|
||||
Log.i(TAG, "Run");
|
||||
ParcelFileDescriptor pfd = null;
|
||||
try {
|
||||
|
@ -124,11 +129,13 @@ public class BlackHoleService extends VpnService implements Runnable {
|
|||
// Drop all packets
|
||||
Log.i(TAG, "Loop start");
|
||||
FileInputStream in = new FileInputStream(pfd.getFileDescriptor());
|
||||
while (!thread.isInterrupted())
|
||||
while (!Thread.currentThread().isInterrupted())
|
||||
in.skip(32768);
|
||||
Log.i(TAG, "Loop exit");
|
||||
|
||||
} catch (Throwable ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
|
||||
} finally {
|
||||
if (pfd != null)
|
||||
try {
|
||||
|
@ -136,8 +143,6 @@ public class BlackHoleService extends VpnService implements Runnable {
|
|||
} catch (IOException ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
thread = null;
|
||||
stopSelf();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,7 @@ package eu.faircode.netguard;
|
|||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.VpnService;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
public class BootReceiver extends BroadcastReceiver {
|
||||
|
@ -15,13 +13,10 @@ public class BootReceiver extends BroadcastReceiver {
|
|||
public void onReceive(final Context context, Intent intent) {
|
||||
Log.i(TAG, "Received " + intent);
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
if (prefs.getBoolean("enabled", false))
|
||||
if (VpnService.prepare(context) == null) {
|
||||
Intent service = new Intent(context, BlackHoleService.class);
|
||||
service.putExtra(BlackHoleService.EXTRA_START, true);
|
||||
Log.i(TAG, "Start service=" + service);
|
||||
context.startService(service);
|
||||
}
|
||||
if (VpnService.prepare(context) == null) {
|
||||
Intent service = new Intent(context, BlackHoleService.class);
|
||||
service.putExtra(BlackHoleService.EXTRA_COMMAND, BlackHoleService.Command.start);
|
||||
context.startService(service);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -46,7 +46,7 @@ public class Rule implements Comparable<Rule> {
|
|||
|
||||
@Override
|
||||
public int compareTo(Rule other) {
|
||||
int i = this.name.compareTo(other.name);
|
||||
return (i == 0 ? this.info.packageName.compareTo(other.info.packageName) : i);
|
||||
int i = name.compareToIgnoreCase(other.name);
|
||||
return (i == 0 ? info.packageName.compareTo(other.info.packageName) : i);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package eu.faircode.netguard;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -31,12 +30,12 @@ public class RuleAdapter extends RecyclerView.Adapter<RuleAdapter.ViewHolder> {
|
|||
|
||||
public ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
this.view = itemView;
|
||||
this.ivIcon = (ImageView) itemView.findViewById(R.id.ivIcon);
|
||||
this.tvName = (TextView) itemView.findViewById(R.id.tvName);
|
||||
this.tvPackage = (TextView) itemView.findViewById(R.id.tvPackage);
|
||||
this.cbWifi = (CheckBox) itemView.findViewById(R.id.cbWifi);
|
||||
this.cbOther = (CheckBox) itemView.findViewById(R.id.cbOther);
|
||||
view = itemView;
|
||||
ivIcon = (ImageView) itemView.findViewById(R.id.ivIcon);
|
||||
tvName = (TextView) itemView.findViewById(R.id.tvName);
|
||||
tvPackage = (TextView) itemView.findViewById(R.id.tvPackage);
|
||||
cbWifi = (CheckBox) itemView.findViewById(R.id.cbWifi);
|
||||
cbOther = (CheckBox) itemView.findViewById(R.id.cbOther);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,65 +44,53 @@ public class RuleAdapter extends RecyclerView.Adapter<RuleAdapter.ViewHolder> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public RuleAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rule, parent, false);
|
||||
ViewHolder vh = new ViewHolder(v);
|
||||
return vh;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
public void onBindViewHolder(final ViewHolder holder, int position) {
|
||||
final Rule rule = listRule.get(position);
|
||||
|
||||
holder.ivIcon.setImageDrawable(rule.getIcon(holder.view.getContext()));
|
||||
holder.tvName.setText(rule.name);
|
||||
holder.tvPackage.setText(rule.info.packageName);
|
||||
|
||||
CompoundButton.OnCheckedChangeListener cbListener = new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
String name;
|
||||
if (buttonView == holder.cbWifi) {
|
||||
name = "wifi";
|
||||
rule.wifi_blocked = isChecked;
|
||||
} else {
|
||||
name = "other";
|
||||
rule.other_blocked = isChecked;
|
||||
}
|
||||
Log.i(TAG, rule.info.packageName + ": " + name + "=" + isChecked);
|
||||
|
||||
Context context = buttonView.getContext();
|
||||
|
||||
SharedPreferences prefs = context.getSharedPreferences(name, Context.MODE_PRIVATE);
|
||||
prefs.edit().putBoolean(rule.info.packageName, isChecked).apply();
|
||||
|
||||
Intent intent = new Intent(context, BlackHoleService.class);
|
||||
intent.putExtra(BlackHoleService.EXTRA_COMMAND, BlackHoleService.Command.reload);
|
||||
context.startService(intent);
|
||||
}
|
||||
};
|
||||
|
||||
holder.cbWifi.setOnCheckedChangeListener(null);
|
||||
holder.cbWifi.setChecked(rule.wifi_blocked);
|
||||
holder.cbWifi.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
|
||||
Context context = compoundButton.getContext();
|
||||
|
||||
rule.wifi_blocked = isChecked;
|
||||
Log.i(TAG, rule.info.packageName + "=" + rule.wifi_blocked);
|
||||
|
||||
SharedPreferences prefs = context.getSharedPreferences("wifi", Context.MODE_PRIVATE);
|
||||
prefs.edit().putBoolean(rule.info.packageName, rule.wifi_blocked).apply();
|
||||
|
||||
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("enabled", false)) {
|
||||
Intent intent = new Intent(context, BlackHoleService.class);
|
||||
intent.putExtra(BlackHoleService.EXTRA_START, true);
|
||||
context.startService(intent);
|
||||
}
|
||||
}
|
||||
});
|
||||
holder.cbWifi.setOnCheckedChangeListener(cbListener);
|
||||
|
||||
holder.cbOther.setOnCheckedChangeListener(null);
|
||||
holder.cbOther.setChecked(rule.other_blocked);
|
||||
holder.cbOther.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
|
||||
Context context = compoundButton.getContext();
|
||||
holder.cbOther.setOnCheckedChangeListener(cbListener);
|
||||
}
|
||||
|
||||
rule.other_blocked = isChecked;
|
||||
Log.i(TAG, rule.info.packageName + "=" + rule.other_blocked);
|
||||
|
||||
SharedPreferences prefs = context.getSharedPreferences("other", Context.MODE_PRIVATE);
|
||||
prefs.edit().putBoolean(rule.info.packageName, rule.other_blocked).apply();
|
||||
|
||||
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("enabled", false)) {
|
||||
Intent intent = new Intent(context, BlackHoleService.class);
|
||||
intent.putExtra(BlackHoleService.EXTRA_START, true);
|
||||
context.startService(intent);
|
||||
}
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public RuleAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.rule, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return this.listRule.size();
|
||||
return listRule.size();
|
||||
}
|
||||
}
|
||||
|
|
35
app/src/main/java/eu/faircode/netguard/Util.java
Normal file
35
app/src/main/java/eu/faircode/netguard/Util.java
Normal file
|
@ -0,0 +1,35 @@
|
|||
package eu.faircode.netguard;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class Util {
|
||||
public static String getSelfVersionName(Context context) {
|
||||
try {
|
||||
PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
|
||||
return pInfo.versionName;
|
||||
} catch (PackageManager.NameNotFoundException ex) {
|
||||
return ex.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static void logExtras(String tag, Intent intent) {
|
||||
logBundle(tag, intent.getExtras());
|
||||
}
|
||||
|
||||
public static void logBundle(String tag, Bundle data) {
|
||||
if (data != null) {
|
||||
Set<String> keys = data.keySet();
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (String key : keys)
|
||||
stringBuilder.append(key).append("=").append(data.get(key)).append("\r\n");
|
||||
Log.d(tag, stringBuilder.toString());
|
||||
}
|
||||
}
|
||||
}
|
38
app/src/main/res/layout/about.xml
Normal file
38
app/src/main/res/layout/about.xml
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/app_name"
|
||||
android:textAppearance="@android:style/TextAppearance.Material.Medium"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvVersion"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:textAppearance="@android:style/TextAppearance.Material.Medium"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="@string/app_copyright"
|
||||
android:textAppearance="@android:style/TextAppearance.Material.Small" />
|
||||
</LinearLayout>
|
|
@ -6,5 +6,6 @@
|
|||
<Switch
|
||||
android:id="@+id/swEnabled"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp" />
|
||||
</RelativeLayout>
|
|
@ -2,8 +2,8 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="6dp">
|
||||
android:layout_marginBottom="4dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivIcon"
|
||||
|
@ -15,9 +15,9 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="6dp">
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvName"
|
||||
|
@ -41,14 +41,14 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:button="@drawable/wifi"
|
||||
android:paddingLeft="3dp" />
|
||||
android:layout_marginLeft="12dp"
|
||||
android:button="@drawable/wifi" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cbOther"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:button="@drawable/other"
|
||||
android:paddingLeft="3dp" />
|
||||
android:layout_marginLeft="12dp"
|
||||
android:button="@drawable/other" />
|
||||
</LinearLayout>
|
9
app/src/main/res/menu/main.xml
Normal file
9
app/src/main/res/menu/main.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/menu_vpn_settings"
|
||||
android:title="@string/menu_vpn_settings" />
|
||||
<item
|
||||
android:id="@+id/menu_about"
|
||||
android:title="@string/menu_about" />
|
||||
</menu>
|
|
@ -1,5 +1,4 @@
|
|||
<resources>
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
</resources>
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
<resources>
|
||||
<string name="app_name">NetGuard for Android</string>
|
||||
<string name="app_name">NetGuard</string>
|
||||
<string name="app_copyright">Copyright \u00A9 2015 by M. Bokhorst (M66B)</string>
|
||||
<string name="menu_vpn_settings">VPN settings</string>
|
||||
<string name="menu_about">About</string>
|
||||
</resources>
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<resources>
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
|
|
Loading…
Add table
Reference in a new issue