Java tutorial
package eu.faircode.adblocker; /* This file is part of NetGuard. NetGuard is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. NetGuard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with NetGuard. If not, see <http://www.gnu.org/licenses/>. Copyright 2015-2016 by Marcel Bokhorst (M66B) */ import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.net.Uri; import android.net.VpnService; import android.os.AsyncTask; import android.os.Build; import android.os.PowerManager; import android.preference.PreferenceManager; import android.provider.Settings; import android.support.annotation.NonNull; import android.support.v4.content.LocalBroadcastManager; import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v4.view.MenuItemCompat; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AlertDialog; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.SearchView; import android.support.v7.widget.SwitchCompat; import android.text.method.LinkMovementMethod; import android.util.Log; import android.util.TypedValue; import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import java.util.List; public class ActivityMain extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = "NetGuard.Main"; private boolean running = false; private ImageView ivIcon; private ImageView ivQueue; private SwitchCompat swEnabled; private ImageView ivMetered; private AdapterRule adapter = null; private MenuItem menuSearch = null; private AlertDialog dialogFirst = null; private AlertDialog dialogVpn = null; private AlertDialog dialogDoze = null; private AlertDialog dialogLegend = null; private AlertDialog dialogAbout = null; private IAB iab = null; private static final int REQUEST_VPN = 1; private static final int REQUEST_INVITE = 2; private static final int REQUEST_LOGCAT = 3; public static final int REQUEST_ROAMING = 4; private static final int MIN_SDK = Build.VERSION_CODES.ICE_CREAM_SANDWICH; public static final String ACTION_RULES_CHANGED = "eu.faircode.adblocker.ACTION_RULES_CHANGED"; public static final String ACTION_QUEUE_CHANGED = "eu.faircode.adblocker.ACTION_QUEUE_CHANGED"; public static final String EXTRA_REFRESH = "Refresh"; public static final String EXTRA_SEARCH = "Search"; public static final String EXTRA_APPROVE = "Approve"; public static final String EXTRA_LOGCAT = "Logcat"; public static final String EXTRA_CONNECTED = "Connected"; public static final String EXTRA_METERED = "Metered"; public static final String EXTRA_SIZE = "Size"; @Override protected void onCreate(Bundle savedInstanceState) { Log.i(TAG, "Create version=" + Util.getSelfVersionName(this) + "/" + Util.getSelfVersionCode(this)); Util.logExtras(getIntent()); if (Build.VERSION.SDK_INT < MIN_SDK) { super.onCreate(savedInstanceState); setContentView(R.layout.android); return; } Util.setTheme(this); super.onCreate(savedInstanceState); setContentView(R.layout.main); swEnabled = (SwitchCompat) findViewById(R.id.swEnabled); running = true; final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); boolean enabled = prefs.getBoolean("enabled", false); boolean initialized = prefs.getBoolean("initialized", false); // Upgrade Receiver.upgrade(initialized, this); if (!getIntent().hasExtra(EXTRA_APPROVE)) { if (enabled) ServiceSinkhole.start("UI", this); else ServiceSinkhole.stop("UI", this); } // Action bar final View actionView = getLayoutInflater().inflate(R.layout.actionmain, null, false); ivIcon = (ImageView) actionView.findViewById(R.id.ivIcon); ivQueue = (ImageView) actionView.findViewById(R.id.ivQueue); ivMetered = (ImageView) actionView.findViewById(R.id.ivMetered); // Icon ivIcon.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View view) { menu_about(); return true; } }); // Title getSupportActionBar().setTitle(null); // Netguard is busy ivQueue.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View view) { int location[] = new int[2]; actionView.getLocationOnScreen(location); Toast toast = Toast.makeText(ActivityMain.this, R.string.msg_queue, Toast.LENGTH_LONG); toast.setGravity(Gravity.TOP | Gravity.START, location[0] + ivQueue.getLeft(), Math.round(location[1] + ivQueue.getBottom() - toast.getView().getPaddingTop())); toast.show(); return true; } }); // On/off switch swEnabled.setChecked(enabled); swEnabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { Log.i(TAG, "Switch=" + isChecked); prefs.edit().putBoolean("enabled", isChecked).apply(); if (isChecked) { try { final Intent prepare = VpnService.prepare(ActivityMain.this); if (prepare == null) { Log.i(TAG, "Prepare done"); onActivityResult(REQUEST_VPN, RESULT_OK, null); } else { // Show dialog LayoutInflater inflater = LayoutInflater.from(ActivityMain.this); View view = inflater.inflate(R.layout.vpn, null, false); dialogVpn = new AlertDialog.Builder(ActivityMain.this).setView(view) .setCancelable(false) .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (running) { Log.i(TAG, "Start intent=" + prepare); try { startActivityForResult(prepare, REQUEST_VPN); } catch (Throwable ex) { Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); Util.sendCrashReport(ex, ActivityMain.this); onActivityResult(REQUEST_VPN, RESULT_CANCELED, null); prefs.edit().putBoolean("enabled", false).apply(); } } } }).setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialogInterface) { dialogVpn = null; } }).create(); dialogVpn.show(); } } catch (Throwable ex) { // Prepare failed Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); Util.sendCrashReport(ex, ActivityMain.this); prefs.edit().putBoolean("enabled", false).apply(); } } else ServiceSinkhole.stop("switch off", ActivityMain.this); } }); if (enabled) checkDoze(); // Network is metered ivMetered.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View view) { int location[] = new int[2]; actionView.getLocationOnScreen(location); Toast toast = Toast.makeText(ActivityMain.this, R.string.msg_metered, Toast.LENGTH_LONG); toast.setGravity(Gravity.TOP | Gravity.START, location[0] + ivMetered.getLeft(), Math.round(location[1] + ivMetered.getBottom() - toast.getView().getPaddingTop())); toast.show(); return true; } }); getSupportActionBar().setDisplayShowCustomEnabled(true); getSupportActionBar().setCustomView(actionView); // Disabled warning TextView tvDisabled = (TextView) findViewById(R.id.tvDisabled); tvDisabled.setVisibility(enabled ? View.GONE : View.VISIBLE); // Application list // RecyclerView rvApplication = (RecyclerView) findViewById(R.id.rvApplication); // rvApplication.setHasFixedSize(true); // rvApplication.setLayoutManager(new LinearLayoutManager(this)); // adapter = new AdapterRule(this); // rvApplication.setAdapter(adapter); // Swipe to refresh TypedValue tv = new TypedValue(); getTheme().resolveAttribute(R.attr.colorPrimary, tv, true); // swipeRefresh = (SwipeRefreshLayout) findViewById(R.id.swipeRefresh); // swipeRefresh.setColorSchemeColors(Color.WHITE, Color.WHITE, Color.WHITE); // swipeRefresh.setProgressBackgroundColorSchemeColor(tv.data); // swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { // @Override // public void onRefresh() { // Rule.clearCache(ActivityMain.this); // ServiceSinkhole.reload("pull", ActivityMain.this); // updateApplicationList(null); // } // }); // Listen for preference changes prefs.registerOnSharedPreferenceChangeListener(this); // Listen for rule set changes IntentFilter ifr = new IntentFilter(ACTION_RULES_CHANGED); LocalBroadcastManager.getInstance(this).registerReceiver(onRulesChanged, ifr); // Listen for queue changes IntentFilter ifq = new IntentFilter(ACTION_QUEUE_CHANGED); LocalBroadcastManager.getInstance(this).registerReceiver(onQueueChanged, ifq); // Listen for added/removed applications IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); intentFilter.addDataScheme("package"); registerReceiver(packageChangedReceiver, intentFilter); // First use if (!initialized) { // Create view LayoutInflater inflater = LayoutInflater.from(this); View view = inflater.inflate(R.layout.first, null, false); TextView tvFirst = (TextView) view.findViewById(R.id.tvFirst); tvFirst.setMovementMethod(LinkMovementMethod.getInstance()); // Show dialog dialogFirst = new AlertDialog.Builder(this).setView(view).setCancelable(false) .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (running) prefs.edit().putBoolean("initialized", true).apply(); } }).setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (running) finish(); } }).setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialogInterface) { dialogFirst = null; } }).create(); dialogFirst.show(); } // Fill application list updateApplicationList(getIntent().getStringExtra(EXTRA_SEARCH)); // Update IAB SKUs try { iab = new IAB(new IAB.Delegate() { @Override public void onReady(IAB iab) { try { iab.updatePurchases(); if (!IAB.isPurchased(ActivityPro.SKU_LOG, ActivityMain.this)) prefs.edit().putBoolean("log", false).apply(); if (!IAB.isPurchased(ActivityPro.SKU_THEME, ActivityMain.this)) { if (!"teal".equals(prefs.getString("theme", "teal"))) prefs.edit().putString("theme", "teal").apply(); } if (!IAB.isPurchased(ActivityPro.SKU_SPEED, ActivityMain.this)) prefs.edit().putBoolean("show_stats", false).apply(); } catch (Throwable ex) { Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); } finally { iab.unbind(); } } }, this); iab.bind(); } catch (Throwable ex) { Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); } checkExtras(getIntent()); } @Override protected void onNewIntent(Intent intent) { Log.i(TAG, "New intent"); Util.logExtras(intent); super.onNewIntent(intent); if (Build.VERSION.SDK_INT >= MIN_SDK) { if (intent.hasExtra(EXTRA_REFRESH)) updateApplicationList(intent.getStringExtra(EXTRA_SEARCH)); else updateSearch(intent.getStringExtra(EXTRA_SEARCH)); checkExtras(intent); } } private void checkExtras(Intent intent) { // Approve request if (intent.hasExtra(EXTRA_APPROVE)) { Log.i(TAG, "Requesting VPN approval"); swEnabled.toggle(); } if (intent.hasExtra(EXTRA_LOGCAT)) { Log.i(TAG, "Requesting logcat"); Intent logcat = getIntentLogcat(); if (logcat.resolveActivity(getPackageManager()) != null) startActivityForResult(logcat, REQUEST_LOGCAT); } } @Override protected void onResume() { DatabaseHelper.getInstance(this).addAccessChangedListener(accessChangedListener); if (adapter != null) adapter.notifyDataSetChanged(); super.onResume(); } @Override protected void onPause() { super.onPause(); DatabaseHelper.getInstance(this).removeAccessChangedListener(accessChangedListener); } @Override public void onDestroy() { Log.i(TAG, "Destroy"); if (Build.VERSION.SDK_INT < MIN_SDK) { super.onDestroy(); return; } running = false; PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this); LocalBroadcastManager.getInstance(this).unregisterReceiver(onRulesChanged); LocalBroadcastManager.getInstance(this).unregisterReceiver(onQueueChanged); unregisterReceiver(packageChangedReceiver); if (dialogFirst != null) { dialogFirst.dismiss(); dialogFirst = null; } if (dialogVpn != null) { dialogVpn.dismiss(); dialogVpn = null; } if (dialogDoze != null) { dialogDoze.dismiss(); dialogDoze = null; } if (dialogLegend != null) { dialogLegend.dismiss(); dialogLegend = null; } if (dialogAbout != null) { dialogAbout.dismiss(); dialogAbout = null; } if (iab != null) { iab.unbind(); iab = null; } super.onDestroy(); } @Override protected void onActivityResult(int requestCode, int resultCode, final Intent data) { Log.i(TAG, "onActivityResult request=" + requestCode + " result=" + requestCode + " ok=" + (resultCode == RESULT_OK)); Util.logExtras(data); if (requestCode == REQUEST_VPN) { // Handle VPN approval SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); prefs.edit().putBoolean("enabled", resultCode == RESULT_OK).apply(); if (resultCode == RESULT_OK) { ServiceSinkhole.start("prepared", this); checkDoze(); } } else if (requestCode == REQUEST_INVITE) { // Do nothing } else if (requestCode == REQUEST_LOGCAT) { // Send logcat by e-mail if (resultCode == RESULT_OK) { Uri target = data.getData(); if (data.hasExtra("org.openintents.extra.DIR_PATH")) target = Uri.parse(target + "/logcat.txt"); Log.i(TAG, "Export URI=" + target); Util.sendLogcat(target, this); } } else { Log.w(TAG, "Unknown activity result request=" + requestCode); super.onActivityResult(requestCode, resultCode, data); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == REQUEST_ROAMING) if (grantResults[0] == PackageManager.PERMISSION_GRANTED) ServiceSinkhole.reload("permission granted", this); } @Override public void onSharedPreferenceChanged(SharedPreferences prefs, String name) { Log.i(TAG, "Preference " + name + "=" + prefs.getAll().get(name)); if ("enabled".equals(name)) { // Get enabled boolean enabled = prefs.getBoolean(name, false); // Display disabled warning TextView tvDisabled = (TextView) findViewById(R.id.tvDisabled); tvDisabled.setVisibility(enabled ? View.GONE : View.VISIBLE); // Check switch state SwitchCompat swEnabled = (SwitchCompat) getSupportActionBar().getCustomView() .findViewById(R.id.swEnabled); if (swEnabled.isChecked() != enabled) swEnabled.setChecked(enabled); } else if ("whitelist_wifi".equals(name) || "screen_wifi".equals(name) || "whitelist_other".equals(name) || "screen_other".equals(name) || "whitelist_roaming".equals(name) || "show_user".equals(name) || "show_system".equals(name) || "show_nointernet".equals(name) || "show_disabled".equals(name) || "sort".equals(name) || "imported".equals(name)) updateApplicationList(null); else if ("manage_system".equals(name)) { invalidateOptionsMenu(); updateApplicationList(null); } else if ("theme".equals(name) || "dark_theme".equals(name)) recreate(); } private DatabaseHelper.AccessChangedListener accessChangedListener = new DatabaseHelper.AccessChangedListener() { @Override public void onChanged() { runOnUiThread(new Runnable() { @Override public void run() { if (adapter != null) adapter.notifyDataSetChanged(); } }); } }; private BroadcastReceiver onRulesChanged = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.i(TAG, "Received " + intent); Util.logExtras(intent); if (adapter != null) if (intent.hasExtra(EXTRA_CONNECTED) && intent.hasExtra(EXTRA_METERED)) { if (intent.getBooleanExtra(EXTRA_CONNECTED, false)) { if (intent.getBooleanExtra(EXTRA_METERED, false)) adapter.setMobileActive(); else adapter.setWifiActive(); ivMetered.setVisibility( Util.isMeteredNetwork(ActivityMain.this) ? View.VISIBLE : View.INVISIBLE); } else { adapter.setDisconnected(); ivMetered.setVisibility(View.INVISIBLE); } } else updateApplicationList(null); } }; private BroadcastReceiver onQueueChanged = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.i(TAG, "Received " + intent); Util.logExtras(intent); int size = intent.getIntExtra(EXTRA_SIZE, -1); ivIcon.setVisibility(size == 0 ? View.VISIBLE : View.GONE); ivQueue.setVisibility(size == 0 ? View.GONE : View.VISIBLE); } }; private BroadcastReceiver packageChangedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.i(TAG, "Received " + intent); Util.logExtras(intent); updateApplicationList(null); } }; private void updateApplicationList(final String search) { Log.i(TAG, "Update search=" + search); new AsyncTask<Object, Object, List<Rule>>() { private boolean refreshing = true; @Override protected List<Rule> doInBackground(Object... arg) { return Rule.getRules(false, ActivityMain.this); } @Override protected void onPostExecute(List<Rule> result) { if (running) { if (adapter != null) { adapter.set(result); updateSearch(search); } } } }.execute(); } private void updateSearch(String search) { if (menuSearch != null) { SearchView searchView = (SearchView) MenuItemCompat.getActionView(menuSearch); if (search == null) { if (menuSearch.isActionViewExpanded()) adapter.getFilter().filter(searchView.getQuery().toString()); } else { MenuItemCompat.expandActionView(menuSearch); searchView.setQuery(search, true); } } } private void checkDoze() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { final Intent doze = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS); PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); if (!pm.isIgnoringBatteryOptimizations(getPackageName()) && getPackageManager().resolveActivity(doze, 0) != null) { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); if (!prefs.getBoolean("nodoze", false)) { LayoutInflater inflater = LayoutInflater.from(this); View view = inflater.inflate(R.layout.doze, null, false); final CheckBox cbDontAsk = (CheckBox) view.findViewById(R.id.cbDontAsk); dialogDoze = new AlertDialog.Builder(this).setView(view).setCancelable(true) .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { prefs.edit().putBoolean("nodoze", cbDontAsk.isChecked()).apply(); startActivity(doze); } }).setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { prefs.edit().putBoolean("nodoze", cbDontAsk.isChecked()).apply(); } }).setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialogInterface) { dialogDoze = null; } }).create(); dialogDoze.show(); } } } } @Override public boolean onCreateOptionsMenu(Menu menu) { if (Build.VERSION.SDK_INT < MIN_SDK) return false; MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main, menu); // Search menuSearch = menu.findItem(R.id.menu_search); MenuItemCompat.setOnActionExpandListener(menuSearch, new MenuItemCompat.OnActionExpandListener() { @Override public boolean onMenuItemActionExpand(MenuItem item) { return true; } @Override public boolean onMenuItemActionCollapse(MenuItem item) { if (getIntent().hasExtra(EXTRA_SEARCH)) finish(); return true; } }); final SearchView searchView = (SearchView) MenuItemCompat.getActionView(menuSearch); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { if (adapter != null) adapter.getFilter().filter(query); searchView.clearFocus(); return true; } @Override public boolean onQueryTextChange(String newText) { if (adapter != null) adapter.getFilter().filter(newText); return true; } }); searchView.setOnCloseListener(new SearchView.OnCloseListener() { @Override public boolean onClose() { if (adapter != null) adapter.getFilter().filter(null); return true; } }); if (!Util.hasValidFingerprint(this) || getIntentInvite(this).resolveActivity(getPackageManager()) == null) menu.removeItem(R.id.menu_invite); if (getIntentSupport().resolveActivity(getPackageManager()) == null) menu.removeItem(R.id.menu_support); return true; } @Override public boolean onPrepareOptionsMenu(Menu menu) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); if (prefs.getBoolean("manage_system", false)) { menu.findItem(R.id.menu_app_user).setChecked(prefs.getBoolean("show_user", true)); menu.findItem(R.id.menu_app_system).setChecked(prefs.getBoolean("show_system", false)); } else { Menu submenu = menu.findItem(R.id.menu_filter).getSubMenu(); submenu.removeItem(R.id.menu_app_user); submenu.removeItem(R.id.menu_app_system); } menu.findItem(R.id.menu_app_nointernet).setChecked(prefs.getBoolean("show_nointernet", true)); menu.findItem(R.id.menu_app_disabled).setChecked(prefs.getBoolean("show_disabled", true)); String sort = prefs.getString("sort", "name"); if ("data".equals(sort)) menu.findItem(R.id.menu_sort_data).setChecked(true); else if ("uid".equals(sort)) menu.findItem(R.id.menu_sort_uid).setChecked(true); else menu.findItem(R.id.menu_sort_name).setChecked(true); return super.onPrepareOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { Log.i(TAG, "Menu=" + item.getTitle()); // Handle item selection SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); switch (item.getItemId()) { case R.id.menu_app_user: item.setChecked(!item.isChecked()); prefs.edit().putBoolean("show_user", item.isChecked()).apply(); return true; case R.id.menu_app_system: item.setChecked(!item.isChecked()); prefs.edit().putBoolean("show_system", item.isChecked()).apply(); return true; case R.id.menu_app_nointernet: item.setChecked(!item.isChecked()); prefs.edit().putBoolean("show_nointernet", item.isChecked()).apply(); return true; case R.id.menu_app_disabled: item.setChecked(!item.isChecked()); prefs.edit().putBoolean("show_disabled", item.isChecked()).apply(); return true; case R.id.menu_sort_name: item.setChecked(true); prefs.edit().putString("sort", "name").apply(); return true; case R.id.menu_sort_uid: item.setChecked(true); prefs.edit().putString("sort", "uid").apply(); return true; case R.id.menu_sort_data: item.setChecked(true); prefs.edit().putString("sort", "data").apply(); return true; case R.id.menu_log: if (IAB.isPurchased(ActivityPro.SKU_LOG, this)) startActivity(new Intent(this, ActivityLog.class)); else startActivity(new Intent(this, ActivityPro.class)); return true; case R.id.menu_settings: startActivity(new Intent(this, ActivitySettings.class)); return true; case R.id.menu_pro: startActivity(new Intent(ActivityMain.this, ActivityPro.class)); return true; case R.id.menu_invite: startActivityForResult(getIntentInvite(this), REQUEST_INVITE); return true; case R.id.menu_legend: menu_legend(); return true; case R.id.menu_support: startActivity(getIntentSupport()); return true; case R.id.menu_about: menu_about(); return true; default: return super.onOptionsItemSelected(item); } } private void menu_legend() { TypedValue tv = new TypedValue(); getTheme().resolveAttribute(R.attr.colorOn, tv, true); int colorOn = tv.data; getTheme().resolveAttribute(R.attr.colorOff, tv, true); int colorOff = tv.data; // Create view LayoutInflater inflater = LayoutInflater.from(this); View view = inflater.inflate(R.layout.legend, null, false); ImageView ivWifiOn = (ImageView) view.findViewById(R.id.ivWifiOn); ImageView ivWifiOff = (ImageView) view.findViewById(R.id.ivWifiOff); ImageView ivOtherOn = (ImageView) view.findViewById(R.id.ivOtherOn); ImageView ivOtherOff = (ImageView) view.findViewById(R.id.ivOtherOff); ImageView ivScreenOn = (ImageView) view.findViewById(R.id.ivScreenOn); ImageView ivHostAllowed = (ImageView) view.findViewById(R.id.ivHostAllowed); ImageView ivHostBlocked = (ImageView) view.findViewById(R.id.ivHostBlocked); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { Drawable wrapWifiOn = DrawableCompat.wrap(ivWifiOn.getDrawable()); Drawable wrapWifiOff = DrawableCompat.wrap(ivWifiOff.getDrawable()); Drawable wrapOtherOn = DrawableCompat.wrap(ivOtherOn.getDrawable()); Drawable wrapOtherOff = DrawableCompat.wrap(ivOtherOff.getDrawable()); Drawable wrapScreenOn = DrawableCompat.wrap(ivScreenOn.getDrawable()); Drawable wrapHostAllowed = DrawableCompat.wrap(ivHostAllowed.getDrawable()); Drawable wrapHostBlocked = DrawableCompat.wrap(ivHostBlocked.getDrawable()); DrawableCompat.setTint(wrapWifiOn, colorOn); DrawableCompat.setTint(wrapWifiOff, colorOff); DrawableCompat.setTint(wrapOtherOn, colorOn); DrawableCompat.setTint(wrapOtherOff, colorOff); DrawableCompat.setTint(wrapScreenOn, colorOn); DrawableCompat.setTint(wrapHostAllowed, colorOn); DrawableCompat.setTint(wrapHostBlocked, colorOff); } // Show dialog dialogLegend = new AlertDialog.Builder(this).setView(view).setCancelable(true) .setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialogInterface) { dialogLegend = null; } }).create(); dialogLegend.show(); } private void menu_about() { // Create view LayoutInflater inflater = LayoutInflater.from(this); View view = inflater.inflate(R.layout.about, null, false); TextView tvVersionName = (TextView) view.findViewById(R.id.tvVersionName); TextView tvVersionCode = (TextView) view.findViewById(R.id.tvVersionCode); Button btnRate = (Button) view.findViewById(R.id.btnRate); TextView tvLicense = (TextView) view.findViewById(R.id.tvLicense); // Show version tvVersionName.setText(Util.getSelfVersionName(this)); if (!Util.hasValidFingerprint(this)) tvVersionName.setTextColor(Color.GRAY); tvVersionCode.setText(Integer.toString(Util.getSelfVersionCode(this))); // Handle license tvLicense.setMovementMethod(LinkMovementMethod.getInstance()); // Handle logcat view.setOnClickListener(new View.OnClickListener() { private short tap = 0; private Toast toast = Toast.makeText(ActivityMain.this, "", Toast.LENGTH_SHORT); @Override public void onClick(View view) { tap++; if (tap == 7) { tap = 0; toast.cancel(); Intent intent = getIntentLogcat(); if (intent.resolveActivity(getPackageManager()) != null) startActivityForResult(intent, REQUEST_LOGCAT); } else if (tap > 3) { toast.setText(Integer.toString(7 - tap)); toast.show(); } } }); // Handle rate btnRate.setVisibility( getIntentRate(this).resolveActivity(getPackageManager()) == null ? View.GONE : View.VISIBLE); btnRate.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivity(getIntentRate(ActivityMain.this)); } }); // Show dialog dialogAbout = new AlertDialog.Builder(this).setView(view).setCancelable(true) .setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialogInterface) { dialogAbout = null; } }).create(); dialogAbout.show(); } private static Intent getIntentInvite(Context context) { Intent intent = new Intent("com.google.android.gms.appinvite.ACTION_APP_INVITE"); intent.setPackage("com.google.android.gms"); intent.putExtra("com.google.android.gms.appinvite.TITLE", context.getString(R.string.menu_invite)); intent.putExtra("com.google.android.gms.appinvite.MESSAGE", context.getString(R.string.msg_try)); intent.putExtra("com.google.android.gms.appinvite.BUTTON_TEXT", context.getString(R.string.msg_try)); // com.google.android.gms.appinvite.DEEP_LINK_URL return intent; } private static Intent getIntentRate(Context context) { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + context.getPackageName())); if (intent.resolveActivity(context.getPackageManager()) == null) intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + context.getPackageName())); return intent; } private static Intent getIntentSupport() { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("https://github.com/M66B/NetGuard/blob/master/FAQ.md")); return intent; } private Intent getIntentLogcat() { Intent intent; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { if (Util.isPackageInstalled("org.openintents.filemanager", this)) { intent = new Intent("org.openintents.action.PICK_DIRECTORY"); } else { intent = new Intent(Intent.ACTION_VIEW); intent.setData( Uri.parse("https://play.google.com/store/apps/details?id=org.openintents.filemanager")); } } else { intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TITLE, "logcat.txt"); } return intent; } }