Java tutorial
/* * Copyright (c) 2014-2015 Luis M. Gallardo D. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser General Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/lgpl.html * */ package com.lgallardo.qbittorrentclient; import android.Manifest; import android.app.AlarmManager; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.FragmentManager; import android.app.FragmentTransaction; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.SearchManager; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.database.Cursor; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.SystemClock; import android.preference.PreferenceManager; import android.provider.MediaStore; import android.provider.Settings; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v4.view.MenuItemCompat; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.SearchView; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import com.google.android.gms.ads.AdRequest; import com.google.android.gms.ads.AdView; import com.nbsp.materialfilepicker.ui.FilePickerActivity; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.regex.Pattern; interface RefreshListener { public void swipeRefresh(); } public class MainActivity extends AppCompatActivity implements RefreshListener { // Torrent Info TAGs protected static final String TAG_NAME = "name"; protected static final String TAG_SIZE = "size"; protected static final String TAG_PROGRESS = "progress"; protected static final String TAG_STATE = "state"; protected static final String TAG_HASH = "hash"; protected static final String TAG_DLSPEED = "dlspeed"; protected static final String TAG_UPSPEED = "upspeed"; protected static final String TAG_ADDEDON = "added_on"; protected static final String TAG_COMPLETIONON = "completion_on"; protected static final String TAG_LABEL = "label"; protected static final String TAG_CATEGORY = "category"; protected static final String TAG_NUMLEECHS = "num_leechs"; protected static final String TAG_NUMSEEDS = "num_seeds"; protected static final String TAG_RATIO = "ratio"; protected static final String TAG_PRIORITY = "priority"; protected static final String TAG_ETA = "eta"; protected static final String TAG_SEQDL = "seq_dl"; protected static final String TAG_FLPIECEPRIO = "f_l_piece_prio"; protected static final String TAG_GLOBAL_MAX_NUM_CONNECTIONS = "max_connec"; protected static final String TAG_MAX_NUM_CONN_PER_TORRENT = "max_connec_per_torrent"; protected static final String TAG_MAX_UPLOADS = "max_uploads"; protected static final String TAG_MAX_NUM_UPSLOTS_PER_TORRENT = "max_uploads_per_torrent"; protected static final String TAG_GLOBAL_UPLOAD = "up_limit"; protected static final String TAG_GLOBAL_DOWNLOAD = "dl_limit"; protected static final String TAG_ALT_UPLOAD = "alt_up_limit"; protected static final String TAG_ALT_DOWNLOAD = "alt_dl_limit"; protected static final String TAG_TORRENT_QUEUEING = "queueing_enabled"; protected static final String TAG_MAX_ACT_DOWNLOADS = "max_active_downloads"; protected static final String TAG_MAX_ACT_UPLOADS = "max_active_uploads"; protected static final String TAG_MAX_ACT_TORRENTS = "max_active_torrents"; protected static final String TAG_URL = "url"; protected static final String TAG_SCHEDULER_ENABLED = "scheduler_enabled"; protected static final String TAG_SCHEDULE_FROM_HOUR = "schedule_from_hour"; protected static final String TAG_SCHEDULE_FROM_MIN = "schedule_from_min"; protected static final String TAG_SCHEDULE_TO_HOUR = "schedule_to_hour"; protected static final String TAG_SCHEDULE_TO_MIN = "schedule_to_min"; protected static final String TAG_SCHEDULER_DAYS = "scheduler_days"; protected static final String TAG_MAX_RATIO_ENABLED = "max_ratio_enabled"; protected static final String TAG_MAX_RATIO = "max_ratio"; protected static final String TAG_MAX_RATIO_ACT = "max_ratio_act"; protected static final int SETTINGS_CODE = 0; protected static final int OPTION_CODE = 1; protected static final int GETPRO_CODE = 2; protected static final int HELP_CODE = 3; protected static final int ADDFILE_CODE = 4; private static final int MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 100; protected static final int SORTBY_NAME = 1; protected static final int SORTBY_SIZE = 2; protected static final int SORTBY_ETA = 3; protected static final int SORTBY_PRIORITY = 4; protected static final int SORTBY_PROGRESS = 5; protected static final int SORTBY_RATIO = 6; protected static final int SORTBY_DOWNLOAD = 7; protected static final int SORTBY_UPLOAD = 8; protected static final int SORTBY_ADDEDON = 9; protected static final int SORTBY_COMPLETEDON = 10; // Cookie (SID - Session ID) public static String cookie = null; public static String qb_version = "3.2.x"; public static String qb_api = "0"; public static String qbittorrentServer = ""; public static LinearLayout headerInfo; // Current state public static String currentState; // Current label public static String currentLabel; protected static com.lgallardo.qbittorrentclient.JSONParser jParser; // Preferences properties protected static String currentServer; protected static String hostname; protected static String subfolder; protected static int port; protected static String protocol; protected static String username; protected static String password; protected static boolean https; protected static boolean auto_refresh; protected static int refresh_period; protected static int connection_timeout; protected static int data_timeout; protected static int sortby_value; protected static boolean reverse_order; protected static boolean dark_ui; protected static String lastState; protected static String lastLabel; protected static long notification_period; protected static boolean header; public static boolean alternative_speeds; // Option protected static String global_max_num_connections; protected static String max_num_conn_per_torrent; protected static String max_uploads; protected static String max_num_upslots_per_torrent; protected static String global_upload; protected static String global_download; protected static String alt_upload; protected static String alt_download; protected static boolean torrent_queueing; protected static String max_act_downloads; protected static String max_act_uploads; protected static String max_act_torrents; protected static long uploadSpeedCount; protected static long downloadSpeedCount; protected static int uploadCount; protected static int downloadCount; protected static boolean schedule_alternative_rate_limits; protected static String alt_from_hour; protected static String alt_from_min; protected static String alt_to_hour; protected static String alt_to_min; protected static String scheduler_days; protected static boolean max_ratio_enabled; protected static String max_ratio; protected static String max_ratio_act; static Torrent[] lines; static String[] names; // Params to get JSON Array private static String[] params = new String[2]; public com.lgallardo.qbittorrentclient.ItemstFragment firstFragment; // myAdapter myadapter public TorrentListAdapter myadapter; // Http status code public int httpStatusCode = 0; // Preferences fields private SharedPreferences sharedPrefs; private StringBuilder builderPrefs; // Drawer properties private CharSequence drawerTitle; private CharSequence title; private String[] navigationDrawerItemTitles; private String[] navigationDrawerServerItems; // private ListView drawerList; public static DrawerItemRecyclerViewAdapter rAdapter; protected RecyclerView mRecyclerView; private RecyclerView.LayoutManager mLayoutManager; // Declaring Layout Manager as a linear layout manager public static DrawerLayout drawerLayout; public static ActionBarDrawerToggle drawerToggle; public static final int DRAWER_ITEM_ACTIONS = 1; public static final int DRAWER_ITEM_SERVERS = 3; public static final int DRAWER_CATEGORY = 5; public static final int DRAWER_LABEL = 6; public static final int DRAWER_LABEL_CATEGORY = 8; private ArrayList<String> labels = new ArrayList<String>(); // Fragments private AboutFragment secondFragment; private HelpFragment helpTabletFragment; private AboutFragment aboutFragment; private boolean okay = false; // Auto-refresh private Handler handler; private boolean canrefresh = true; // Ads View private AdView adView; // For checking if the app is visible private boolean activityIsVisible = true; // Item list position private int itemPosition = 0; // Searching field private String searchField = ""; private String qbQueryString = "query"; // Alarm manager private AlarmManager alarmMgr; private PendingIntent alarmIntent; // New ToolBar in Material Desing Toolbar toolbar; public static boolean listViewRefreshing; // Search bar in Material Design private MenuItem mSearchAction; private boolean isSearchOpened = false; private EditText editSearch; // Package info public static String packageName; public static String packageVersion; // Action (states) public static final ArrayList<String> actionStates = new ArrayList<>( Arrays.asList("all", "downloading", "completed", "seeding", "pause", "active", "inactive")); // Authentication error counter private int connection403ErrorCounter = 0; // Alternative rate private MenuItem altSpeedLimitsMenuItem; private boolean enable_notifications; // SSID properties protected static String ssid; protected static String local_hostname; protected static int local_port; // Keystore for self-signed certificate protected static String keystore_path; protected static String keystore_password; // Torrent url private String urlTorrent; private Toast toast; private AsyncTask<String, Integer, Torrent[]> qbTask; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Get preferences getSettings(); // Set alarm for checking completed torrents, if not set if (PendingIntent.getBroadcast(getApplication(), 0, new Intent(getApplication(), NotifierService.class), PendingIntent.FLAG_NO_CREATE) == null) { // Set Alarm for checking completed torrents alarmMgr = (AlarmManager) getApplication().getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(getApplication(), NotifierService.class); alarmIntent = PendingIntent.getBroadcast(getApplication(), 0, intent, 0); alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 5000, notification_period, alarmIntent); } // Set alarm for RSS checking, if not set if (PendingIntent.getBroadcast(getApplication(), 0, new Intent(getApplication(), RSSService.class), PendingIntent.FLAG_NO_CREATE) == null) { // Set Alarm for checking completed torrents alarmMgr = (AlarmManager) getApplication().getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(getApplication(), RSSService.class); alarmIntent = PendingIntent.getBroadcast(getApplication(), 0, intent, 0); alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 5000, AlarmManager.INTERVAL_DAY, alarmIntent); } // Set Theme (It must be fore inflating or setContentView) if (dark_ui) { this.setTheme(R.style.Theme_Dark); if (Build.VERSION.SDK_INT >= 21) { getWindow().setNavigationBarColor(getResources().getColor(R.color.Theme_Dark_toolbarBackground)); getWindow().setStatusBarColor(getResources().getColor(R.color.Theme_Dark_toolbarBackground)); } } else { this.setTheme(R.style.Theme_Light); if (Build.VERSION.SDK_INT >= 21) { getWindow().setNavigationBarColor(getResources().getColor(R.color.primary)); } } setContentView(R.layout.activity_main); toolbar = (Toolbar) findViewById(R.id.app_bar); if (dark_ui) { toolbar.setBackgroundColor(getResources().getColor(R.color.Theme_Dark_primary)); } setSupportActionBar(toolbar); // Set App title setTitle(R.string.app_shortname); // Drawer menu navigationDrawerServerItems = getResources().getStringArray(R.array.qBittorrentServers); navigationDrawerItemTitles = getResources().getStringArray(R.array.navigation_drawer_items_array); drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); // drawerList = (ListView) findViewById(R.id.left_drawer); mRecyclerView = (RecyclerView) findViewById(R.id.RecyclerView); // Assigning the RecyclerView Object to the xml View mRecyclerView.setHasFixedSize(true); // Letting the system know that the list objects are ArrayList<DrawerItem> serverItems = new ArrayList<DrawerItem>(); ArrayList<DrawerItem> actionItems = new ArrayList<DrawerItem>(); // ArrayList<ObjectDrawerItem> labelItems = new ArrayList<ObjectDrawerItem>(); ArrayList<DrawerItem> settingsItems = new ArrayList<DrawerItem>(); // Add server category serverItems.add(new DrawerItem(R.drawable.ic_drawer_servers, getResources().getString(R.string.drawer_servers_category), DRAWER_CATEGORY, false, null)); // Server items int currentServerValue = 1; try { currentServerValue = Integer.parseInt(MainActivity.currentServer); } catch (NumberFormatException e) { } for (int i = 0; i < navigationDrawerServerItems.length; i++) { serverItems.add(new DrawerItem(R.drawable.ic_drawer_subitem, navigationDrawerServerItems[i], DRAWER_ITEM_SERVERS, ((i + 1) == currentServerValue), "changeCurrentServer")); } // Add actions actionItems.add(new DrawerItem(R.drawable.ic_drawer_all, navigationDrawerItemTitles[0], DRAWER_ITEM_ACTIONS, lastState.equals("all"), "refreshAll")); actionItems.add(new DrawerItem(R.drawable.ic_drawer_downloading, navigationDrawerItemTitles[1], DRAWER_ITEM_ACTIONS, lastState.equals("downloading"), "refreshDownloading")); actionItems.add(new DrawerItem(R.drawable.ic_drawer_completed, navigationDrawerItemTitles[2], DRAWER_ITEM_ACTIONS, lastState.equals("completed"), "refreshCompleted")); actionItems.add(new DrawerItem(R.drawable.ic_drawer_seeding, navigationDrawerItemTitles[3], DRAWER_ITEM_ACTIONS, lastState.equals("seeding"), "refreshSeeding")); actionItems.add(new DrawerItem(R.drawable.ic_drawer_paused, navigationDrawerItemTitles[4], DRAWER_ITEM_ACTIONS, lastState.equals("pause"), "refreshPaused")); actionItems.add(new DrawerItem(R.drawable.ic_drawer_active, navigationDrawerItemTitles[5], DRAWER_ITEM_ACTIONS, lastState.equals("active"), "refreshActive")); actionItems.add(new DrawerItem(R.drawable.ic_drawer_inactive, navigationDrawerItemTitles[6], DRAWER_ITEM_ACTIONS, lastState.equals("inactive"), "refreshInactive")); // Add labels // Add settings actions settingsItems.add(new DrawerItem(R.drawable.ic_action_options, navigationDrawerItemTitles[7], DRAWER_ITEM_ACTIONS, false, "openOptions")); settingsItems.add(new DrawerItem(R.drawable.ic_drawer_settings, navigationDrawerItemTitles[8], DRAWER_ITEM_ACTIONS, false, "openSettings")); if (packageName.equals("com.lgallardo.qbittorrentclient")) { settingsItems.add(new DrawerItem(R.drawable.ic_drawer_pro, navigationDrawerItemTitles[9], DRAWER_ITEM_ACTIONS, false, "getPro")); settingsItems.add(new DrawerItem(R.drawable.ic_drawer_help, navigationDrawerItemTitles[10], DRAWER_ITEM_ACTIONS, false, "openHelp")); } else { settingsItems.add(new DrawerItem(R.drawable.ic_drawer_help, navigationDrawerItemTitles[9], DRAWER_ITEM_ACTIONS, false, "openHelp")); } rAdapter = new DrawerItemRecyclerViewAdapter(getApplicationContext(), this, serverItems, actionItems, settingsItems, null); rAdapter.notifyDataSetChanged(); // drawerList.setAdapter(adapter); mRecyclerView.setAdapter(rAdapter); mLayoutManager = new LinearLayoutManager(this); // Creating a layout Manager mRecyclerView.setLayoutManager(mLayoutManager); // Setting the layout Manager // Set selection according to last state setSelectionAndTitle(lastState); // Get drawer title title = drawerTitle = getTitle(); // Add the application icon control code inside MainActivity onCreate drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); // New ActionBarDrawerToggle for Google Material Desing (v7) drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close) { /** * Called when a drawer has settled in a completely closed state. */ public void onDrawerClosed(View view) { super.onDrawerClosed(view); // getSupportActionBar().setTitle(title); } /** * Called when a drawer has settled in a completely open state. */ public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); // getSupportActionBar().setTitle(drawerTitle); // setTitle(R.string.app_shortname); } }; drawerLayout.setDrawerListener(drawerToggle); getSupportActionBar().setDisplayHomeAsUpEnabled(false); getSupportActionBar().setHomeButtonEnabled(false); // Get options and save them as shared preferences qBittorrentOptions qso = new qBittorrentOptions(); qso.execute(new String[] { qbQueryString + "/preferences", "getSettings" }); // If it was awoken from an intent-filter, // get intent from the intent filter and Add URL torrent addTorrentByIntent(getIntent()); // Fragments // Check whether the activity is using the layout version with // the fragment_container FrameLayout. If so, we must add the first // fragment if (findViewById(R.id.fragment_container) != null) { // However, if we're being restored from a previous state, // then we don't need to do anything and should return or else // we could end up with overlapping fragments. // if (savedInstanceState != null) { // return; // } // This fragment will hold the list of torrents if (firstFragment == null) { firstFragment = new com.lgallardo.qbittorrentclient.ItemstFragment(); } // This fragment will hold the list of torrents helpTabletFragment = new HelpFragment(); // Set the second fragments container firstFragment.setSecondFragmentContainer(R.id.content_frame); // This i the second fragment, holding a default message at the // beginning secondFragment = new AboutFragment(); // Add the fragment to the 'list_frame' FrameLayout FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); if (fragmentManager.findFragmentByTag("firstFragment") == null) { fragmentTransaction.add(R.id.list_frame, helpTabletFragment, "firstFragment"); } else { fragmentTransaction.replace(R.id.list_frame, helpTabletFragment, "firstFragment"); } if (fragmentManager.findFragmentByTag("secondFragment") == null) { fragmentTransaction.add(R.id.content_frame, secondFragment, "secondFragment"); } else { fragmentTransaction.replace(R.id.content_frame, secondFragment, "secondFragment"); } fragmentTransaction.commit(); // Second fragment will be added in ItemsFragment's onListItemClick method } else { // Phones handle just one fragment // Create an instance of ItemsFragments if (firstFragment == null) { firstFragment = new com.lgallardo.qbittorrentclient.ItemstFragment(); } firstFragment.setSecondFragmentContainer(R.id.one_frame); // This is the about fragment, holding a default message at the // beginning secondFragment = new AboutFragment(); // If we're being restored from a previous state, // then we don't need to do anything and should return or else // we could end up with overlapping fragments. // if (savedInstanceState != null) { // // // Handle Item list empty due to Fragment stack // try { // FragmentManager fm = getFragmentManager(); // // if (fm.getBackStackEntryCount() == 1 && fm.findFragmentById(R.id.one_frame) instanceof com.lgallardo.qbittorrentclient.TorrentDetailsFragment) { // // refreshCurrent(); // // } // } // catch (Exception e) { // } // // return; // } // Add the fragment to the 'list_frame' FrameLayout FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); if (fragmentManager.findFragmentByTag("firstFragment") == null) { fragmentTransaction.add(R.id.one_frame, secondFragment, "firstFragment"); } else { fragmentTransaction.replace(R.id.one_frame, secondFragment, "firstFragment"); } // if torrent details was loaded reset back button stack for (int i = 0; i < fragmentManager.getBackStackEntryCount(); ++i) { fragmentManager.popBackStack(); } fragmentTransaction.commit(); } // Activity is visible activityIsVisible = true; // First refresh refreshCurrent(); handler = new Handler(); handler.postDelayed(m_Runnable, refresh_period); // Load banner loadBanner(); } // Search bar in Material Design @Override public boolean onPrepareOptionsMenu(Menu menu) { altSpeedLimitsMenuItem = menu.findItem(R.id.action_toggle_alternative_rate); return super.onPrepareOptionsMenu(menu); } // Set selection and title on drawer public void setSelectionAndTitle(String state) { // Set selection according to last state if (state != null) { currentState = state; if (state.equals("all")) { setTitle(navigationDrawerItemTitles[0]); } if (state.equals("downloading")) { setTitle(navigationDrawerItemTitles[1]); } if (state.equals("completed")) { setTitle(navigationDrawerItemTitles[2]); } if (state.equals("seeding")) { setTitle(navigationDrawerItemTitles[3]); } if (state.equals("pause")) { setTitle(navigationDrawerItemTitles[4]); } if (state.equals("active")) { setTitle(navigationDrawerItemTitles[5]); } if (state.equals("inactive")) { setTitle(navigationDrawerItemTitles[6]); } } else { // Set title to All setTitle(navigationDrawerItemTitles[0]); } } @Override public void onDestroy() { super.onDestroy(); } @Override public void onResume() { super.onResume(); activityIsVisible = true; // Handle Item list empty due to Fragment stack try { FragmentManager fm = getFragmentManager(); FragmentTransaction fragmentTransaction = fm.beginTransaction(); if (fm.getBackStackEntryCount() == 0 && firstFragment.getSecondFragmentContainer() == R.id.one_frame && fm.findFragmentById( R.id.one_frame) instanceof com.lgallardo.qbittorrentclient.ItemstFragment) { com.lgallardo.qbittorrentclient.ItemstFragment fragment = (com.lgallardo.qbittorrentclient.ItemstFragment) fm .findFragmentById(R.id.one_frame); if (fragment.getListView().getCount() == 0) { // Create the about fragment aboutFragment = new AboutFragment(); fragmentTransaction.replace(R.id.one_frame, aboutFragment, "firstFragment"); fragmentTransaction.commit(); // Se title // setTitle(navigationDrawerItemTitles[drawerList.getCheckedItemPosition()]); // setTitle(navigationDrawerItemTitles[DrawerItemRecyclerViewAdapter.actionPosition]); setSelectionAndTitle(lastState); // Close Contextual Action Bar if (firstFragment != null && firstFragment.mActionMode != null) { firstFragment.mActionMode.finish(); } // Refresh current list refreshCurrent(); } } if (fm.getBackStackEntryCount() == 0 && firstFragment.getSecondFragmentContainer() == R.id.content_frame && (fm.findFragmentByTag("secondFragment") instanceof AboutFragment)) { // Create the about fragment aboutFragment = new AboutFragment(); fragmentTransaction.replace(R.id.content_frame, aboutFragment, "secondFragment"); fragmentTransaction.commit(); // Se title // setTitle(navigationDrawerItemTitles[drawerList.getCheckedItemPosition()]); // setTitle(navigationDrawerItemTitles[DrawerItemRecyclerViewAdapter.actionPosition]); setSelectionAndTitle(lastState); // Close Contextual Action Bar if (firstFragment != null && firstFragment.mActionMode != null) { firstFragment.mActionMode.finish(); } // Refresh current list refreshCurrent(); } } catch (Exception e) { } } @Override public void onPause() { super.onPause(); activityIsVisible = false; // // Cancel toast messages // if(toast != null) { // toast.cancel(); // } } // @Override // protected void onStop() { // super.onStop(); // // // Cancel toast messages // if(toast != null) { // toast.cancel(); // } // // // Cancel qbTask // if(qbTask != null){ // qbTask.cancel(true); // } // // } // Load Banner public void loadBanner() { if (packageName.equals("com.lgallardo.qbittorrentclient")) { // Look up the AdView as a resource and load a request. adView = (AdView) this.findViewById(R.id.adView); AdRequest adRequest = new AdRequest.Builder().build(); // Start loading the ad in the background. adView.loadAd(adRequest); } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // TODO: Delete outState.putInt("itemPosition", itemPosition); } // Auto-refresh runnable private final Runnable m_Runnable = new Runnable() { public void run() { if (auto_refresh == true && canrefresh == true && activityIsVisible == true) { refreshCurrent(); } MainActivity.this.handler.postDelayed(m_Runnable, refresh_period); } };// runnable public void refreshCurrent() { // if (!hostname.equals("")) { // switch (drawerList.getCheckedItemPosition()) { switch (actionStates.indexOf(currentState)) { case 0: refresh("all", currentLabel); break; case 1: refresh("downloading", currentLabel); break; case 2: refresh("completed", currentLabel); break; case 3: refresh("seeding", currentLabel); break; case 4: refresh("pause", currentLabel); break; case 5: refresh("active", currentLabel); break; case 6: refresh("inactive", currentLabel); break; default: refresh(); break; } // } } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.mSwipeRefreshLayout.isRefreshing()) { return; } // if (v.getId() == R.id.theList) { AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; // Log.d("Debug", "Chosen: " + menuInfo.toString()); // Log.d("Debug", "Chosen: " + info.position); // Log.d("Debug", "View id: " + v.getId()); // Log.d("Debug", "View id: " + R.id.RecyclerViewTrackers); if (v.getId() == R.id.RecyclerViewContentFiles) { getMenuInflater().inflate(R.menu.menu_file_contextual, menu); } // } } @Override public boolean onContextItemSelected(MenuItem item) { AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); // Log.d("Debug", "Item name: " + getResources().getResourceEntryName(item.getItemId())); // // Log.d("Debug", "Item position: " + TorrentDetailsFragment.fileContentRowPosition); switch (item.getItemId()) { case R.id.action_file_dont_download: // Log.d("Debug", "Don't download"); setFilePrio(TorrentDetailsFragment.hashToUpdate, TorrentDetailsFragment.fileContentRowPosition, 0); return true; case R.id.action_file_normal_priority: // Log.d("Debug", "Normal priority"); setFilePrio(TorrentDetailsFragment.hashToUpdate, TorrentDetailsFragment.fileContentRowPosition, 1); return true; case R.id.action_file_high_priority: // Log.d("Debug", "High priority"); setFilePrio(TorrentDetailsFragment.hashToUpdate, TorrentDetailsFragment.fileContentRowPosition, 2); return true; case R.id.action_file_maximum_priority: // Log.d("Debug", "Maximum priority"); setFilePrio(TorrentDetailsFragment.hashToUpdate, TorrentDetailsFragment.fileContentRowPosition, 7); return true; default: // Log.d("Debug", "default priority?"); return super.onOptionsItemSelected(item); } } @Override public void setTitle(CharSequence title) { this.title = title; getSupportActionBar().setTitle(title); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); drawerToggle.syncState(); } @Override public void onBackPressed() { // If drawer is opened, close it if (drawerLayout.isDrawerOpen(mRecyclerView)) { drawerLayout.closeDrawer(mRecyclerView); return; } FragmentManager fm = getFragmentManager(); com.lgallardo.qbittorrentclient.ItemstFragment fragment = null; // Close Contextual Action Bar if (com.lgallardo.qbittorrentclient.ItemstFragment.mActionMode != null) { com.lgallardo.qbittorrentclient.ItemstFragment.mActionMode.finish(); } else { if (fm.getBackStackEntryCount() == 0) { // Set About first load to true AboutFragment.isFragmentFirstLoaded = true; // Close the app this.finish(); } else { // Disable refreshing disableRefreshSwipeLayout(); // Enable toolbar title getSupportActionBar().setDisplayShowTitleEnabled(true); fm.popBackStack(); } } if (findViewById(R.id.one_frame) != null) { getSupportActionBar().setDisplayShowTitleEnabled(true); MainActivity.drawerToggle.setDrawerIndicatorEnabled(true); MainActivity.drawerToggle.setToolbarNavigationClickListener(ItemstFragment.originalListener); // Set title setSelectionAndTitle(MainActivity.currentState); if (headerInfo != null) { if (header) { headerInfo.setVisibility(View.VISIBLE); } else { headerInfo.setVisibility(View.GONE); } } } } protected void refreshFromDrawerAction(String state, String title) { setTitle(title); refreshSwipeLayout(); refresh(state, currentLabel); saveLastState(state); } private void refresh() { refresh("all", currentLabel); } private void refresh(String state, String label) { // If Contextual Action Bar is open, don't refresh if (firstFragment != null && firstFragment.mActionMode != null) { return; } if (qb_version.equals("2.x")) { qbQueryString = "json"; params[0] = qbQueryString + "/events"; } if (qb_version.equals("3.1.x")) { qbQueryString = "json"; params[0] = qbQueryString + "/torrents"; } if (qb_version.equals("3.2.x")) { qbQueryString = "query"; params[0] = qbQueryString + "/torrents?filter=" + state; // Get API version in case it hasn't been gotten before if (qb_api == null || qb_api.equals("") || qb_api.equals("0")) { new qBittorrentApiTask().execute(new Intent()); } // Label if (label != null && !label.equals(getResources().getString(R.string.drawer_label_all))) { if (label.equals(getResources().getString(R.string.drawer_label_unlabeled))) { label = ""; } if (!labels.contains(label)) { label = getResources().getString(R.string.drawer_label_all); } saveLastLabel(label); // Log.d("Debug", "Label filter: " + label); try { if (!label.equals(getResources().getString(R.string.drawer_label_all))) { // I used a dummy URL to encode label String labelEncoded = Uri.encode("http://www.dummy.org?label=" + label); // then I got the the encoded label labelEncoded = labelEncoded.substring(labelEncoded.indexOf("%3D") + 3); // to build the url and pass it to params[0] if (Integer.parseInt(MainActivity.qb_api) < 10) { params[0] = params[0] + "&label=" + labelEncoded; } else { params[0] = params[0] + "&category=" + labelEncoded; } } } catch (Exception e) { Log.d("Debug", "[Main] Label Exception: " + e.toString()); } } else { // Log.d("Debug", "Label filter2: " + label); } } params[1] = state; ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.isConnected() && !networkInfo.isFailover()) { // Logs for reporting if (CustomLogger.isMainActivityReporting()) { generateSettingsReport(); } if (hostname.equals("")) { qBittorrentNoSettingsFoundDialog(R.string.info, R.string.about_help1); } else { // Log.d("Report", "Report: " + CustomLogger.getReport()); if (qb_version.equals("3.2.x") && (cookie == null || cookie.equals(""))) { // Request new cookie and execute task in background if (connection403ErrorCounter > 1) { toastText(R.string.error403); httpStatusCode = 0; disableRefreshSwipeLayout(); } else { new qBittorrentCookieTask().execute(params); } } else { if (connection403ErrorCounter > 1) { if (cookie != null && !cookie.equals("")) { // Only toasts the message if there is not a cookie set before toastText(R.string.error403); cookie = null; } httpStatusCode = 0; disableRefreshSwipeLayout(); } else { // Execute the task in background qbTask = new qBittorrentTask().execute(params); // Check if alternative speed limit is set new qBittorrentCommand().execute(new String[] { "alternativeSpeedLimitsEnabled", "" }); } } } } else { // Connection Error message toastText(R.string.connection_error); disableRefreshSwipeLayout(); } } private void toastText(int message) { if (activityIsVisible == true) { toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT); toast.show(); } } // This method adds information to generate a report for support private void generateSettingsReport() { CustomLogger.saveReportMessage("Main", "currentServer: " + currentServer); CustomLogger.saveReportMessage("Main", "hostname: " + hostname); CustomLogger.saveReportMessage("Main", "https: " + https); CustomLogger.saveReportMessage("Main", "port: " + port); CustomLogger.saveReportMessage("Main", "subfolder: " + subfolder); CustomLogger.saveReportMessage("Main", "protocol: " + protocol); CustomLogger.saveReportMessage("Main", "username: " + username); CustomLogger.saveReportMessage("Main", "password: [is" + (password.isEmpty() ? "" : " not") + " empty]"); CustomLogger.saveReportMessage("Main", "Auto-refresh?: " + auto_refresh); CustomLogger.saveReportMessage("Main", "Refresh period: " + refresh_period); CustomLogger.saveReportMessage("Main", "Connection timeout: " + connection_timeout); CustomLogger.saveReportMessage("Main", "Data timeout: " + data_timeout); CustomLogger.saveReportMessage("Main", "dark_ui: " + dark_ui); CustomLogger.saveReportMessage("Main", "qb_version: " + qb_version); CustomLogger.saveReportMessage("Main", "qBittorrent server: " + qbittorrentServer); CustomLogger.saveReportMessage("Main", "Cookie: [is" + ((cookie != null && cookie.isEmpty()) ? "" : " not") + " empty]"); CustomLogger.saveReportMessage("Main", "enable_notifications: " + enable_notifications); CustomLogger.saveReportMessage("Main", "notification_period: " + notification_period); CustomLogger.saveReportMessage("Main", "packageName: " + packageName); CustomLogger.saveReportMessage("Main", "packageVersion: " + packageVersion); CustomLogger.saveReportMessage("Main", "Current state: " + currentState); CustomLogger.saveReportMessage("Main", "Last state: " + lastState); CustomLogger.saveReportMessage("Main", "Current Label: " + currentLabel); } public void emailReport() { if (CustomLogger.isMainActivityReporting()) { Intent emailIntent = new Intent(Intent.ACTION_SEND); emailIntent.setType("text/plain"); emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { "lgallard+qbcontroller@gmail.com" }); emailIntent.putExtra(Intent.EXTRA_SUBJECT, "qBittorrentController report"); // Include report emailIntent.putExtra(Intent.EXTRA_TEXT, CustomLogger.getReport()); // Delete report CustomLogger.setMainActivityReporting(false); CustomLogger.deleteMainReport(); CustomLogger.deleteNotifierReport(); // Launch email chooser startActivity(Intent.createChooser(emailIntent, "Send qBittorrent report...")); // Reporting - Finish report CustomLogger.setMainActivityReporting(false); } } @Override protected void onNewIntent(Intent intent) { handleIntent(intent); } private void handleIntent(Intent intent) { if (Intent.ACTION_SEARCH.equals(intent.getAction())) { // Use the query to search your data somehow searchField = intent.getStringExtra(SearchManager.QUERY); // Log.d("Debug", "Search for..." + searchField); // Autorefresh refreshSwipeLayout(); refreshCurrent(); } if (Intent.ACTION_VIEW.equals(intent.getAction())) { // Add torrent (file, url or magnet) addTorrentByIntent(intent); // // Activity is visible activityIsVisible = true; // Autorefresh refreshCurrent(); } try { if (intent.getStringExtra("from").equals("NotifierService")) { saveLastState("completed"); setSelectionAndTitle("completed"); refresh("completed", currentLabel); } if (intent.getStringExtra("from").equals("RSSItemActivity")) { // Add torrent (file, url or magnet) addTorrentByIntent(intent); // // Activity is visble activityIsVisible = true; // Autorefresh refreshCurrent(); } // Log.d("Debug", "lastState (handle intent):End " ); } catch (Exception e) { // Log.e("Debug", "Handle intent: " + e.toString() ); } } // Get path from content reference, such as content//downloads/0 // Taken from here http://stackoverflow.com/questions/9194361/how-to-use-android-downloadmanager public static String getFilePathFromUri(Context c, Uri uri) { String filePath = null; if ("content".equals(uri.getScheme())) { String[] filePathColumn = { MediaStore.MediaColumns.DATA }; ContentResolver contentResolver = c.getContentResolver(); Cursor cursor = contentResolver.query(uri, filePathColumn, null, null, null); if (cursor != null && cursor.moveToFirst()) { int columnIndex = cursor.getColumnIndex(filePathColumn[0]); filePath = cursor.getString(columnIndex); cursor.close(); } } else if ("file".equals(uri.getScheme())) { filePath = new File(uri.getPath()).getAbsolutePath(); } return filePath; } private void handleUrlTorrent() { // permission was granted, yay! Do the // contacts-related task you need to do. // if there is not a path to the file, open de file picker if (urlTorrent == null) { openFilePicker(); } else { try { if (urlTorrent.substring(0, 7).equals("content")) { urlTorrent = "file://" + getFilePathFromUri(this, Uri.parse(urlTorrent)); } if (urlTorrent.substring(0, 4).equals("file")) { // File addTorrentFile(Uri.parse(urlTorrent).getPath()); } else { urlTorrent = Uri.decode(URLEncoder.encode(urlTorrent, "UTF-8")); // If It is a valid torrent or magnet link if (urlTorrent.contains(".torrent") || urlTorrent.contains("magnet:")) { // Log.d("Debug", "URL: " + urlTorrent); addTorrent(urlTorrent); } else { // Open not valid torrent or magnet link in browser Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(urlTorrent)); startActivity(browserIntent); } } } catch (UnsupportedEncodingException e) { Log.e("Debug", "Check URL: " + e.toString()); } catch (NullPointerException e) { Log.e("Debug", "urlTorrent is null: " + e.toString()); } catch (IOException e) { e.printStackTrace(); } } } private void addTorrentByIntent(Intent intent) { // Log.d("Debug", "addTorrentByIntent invoked"); urlTorrent = intent.getDataString(); // // Log.d("Debug", "urlTorrent: "+ urlTorrent); // Log.d("Debug", "intent: " + intent.toString()); if (urlTorrent != null && urlTorrent.length() != 0) { // Check dangerous permissions checkDangerousPermissions(); } try { if (intent.getStringExtra("from").equals("NotifierService")) { saveLastState("completed"); setSelectionAndTitle("completed"); refresh("completed", currentLabel); } } catch (NullPointerException npe) { } } private void checkDangerousPermissions() { // Check Dangerous permissions (Android 6.0+, API 23+) if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { genericOkDialog(R.string.error_permission, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ActivityCompat.requestPermissions(MainActivity.this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }, MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE); } }); } else { // No explanation needed, request the permission. ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }, MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE); } } else { // Permissions granted handleUrlTorrent(); } } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permissions granted handleUrlTorrent(); } else { // Permission denied // Should we show an explanation? if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { genericOkCancelDialog(R.string.error_grant_permission, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Intent appIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); appIntent.setData(Uri.parse("package:" + packageName)); startActivityForResult(appIntent, 0); } }); } return; } } } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); // Retrieve the SearchView and plug it into SearchManager final SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search)); SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE); searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default // Handle open/close SearchView (using an item menu) final MenuItem menuItem = menu.findItem(R.id.action_search); // When back is pressed or the SearchView is close, delete the query field // and close the SearchView using the item menu searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View view, boolean queryTextFocused) { if (!queryTextFocused) { menuItem.collapseActionView(); searchView.setQuery("", false); searchField = ""; refreshSwipeLayout(); refreshCurrent(); } } }); // This must be implemented to override defaul searchview behaviour, in order to // make it work with tablets searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { //Log.d("Debug", "onQueryTextSubmit - searchField: " + query); // false: don't actually send the query. We are going to do something different searchView.setQuery(query, false); // Set the variable we use in the intent to perform the search searchField = query; // Refresh using the search field refreshSwipeLayout(); refreshCurrent(); // Close the soft keyboard InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(menuItem.getActionView().getWindowToken(), 0); // Here true means, override default searchview query return true; } @Override public boolean onQueryTextChange(String newText) { return false; } }); // There is a bug setting the hint from searchable.xml, so force it searchView.setQueryHint(getResources().getString(R.string.search_hint)); return true; } public void popBackStackPhoneView() { // Set default toolbar behaviour android.support.v7.app.ActionBar actionBar = getSupportActionBar(); actionBar.setDisplayHomeAsUpEnabled(false); drawerToggle.setDrawerIndicatorEnabled(true); actionBar.setHomeButtonEnabled(true); drawerToggle.setToolbarNavigationClickListener(ItemstFragment.originalListener); // Set title setSelectionAndTitle(MainActivity.currentState); // Show herderInfo in phone's view if (findViewById(R.id.one_frame) != null) { if (headerInfo != null) { if (header) { headerInfo.setVisibility(View.VISIBLE); } else { headerInfo.setVisibility(View.GONE); } } } else { headerInfo.setVisibility(View.VISIBLE); } getFragmentManager().popBackStack(); } @Override public boolean onOptionsItemSelected(MenuItem item) { Builder builder; AlertDialog dialog; if (drawerToggle.onOptionsItemSelected(item)) { return true; } // Enable title (just in case) getSupportActionBar().setDisplayShowTitleEnabled(true); switch (item.getItemId()) { case R.id.action_refresh: swipeRefresh(); return true; case R.id.action_add_file: // Add torrent file openFilePicker(); return true; case R.id.action_add_url: // Add torrent URL addUrlTorrent(); return true; case R.id.action_rss: // Open RSS Activity Intent intent = new Intent(getBaseContext(), com.lgallardo.qbittorrentclient.RSSFeedActivity.class); startActivity(intent); return true; case R.id.action_pause: if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate != null) { pauseTorrent(com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate); // if (findViewById(R.id.one_frame) != null) { // popBackStackPhoneView(); // } } return true; case R.id.action_resume: if (TorrentDetailsFragment.hashToUpdate != null) { startTorrent(TorrentDetailsFragment.hashToUpdate); // if (findViewById(R.id.one_frame) != null) { // popBackStackPhoneView(); // } } return true; case R.id.action_delete: okay = false; if (!isFinishing()) { builder = new Builder(this); // Message builder.setMessage(R.string.dm_deleteTorrent).setTitle(R.string.dt_deleteTorrent); // Cancel builder.setNeutralButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User cancelled the dialog okay = false; } }); // Ok builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User accepted the dialog if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate != null) { deleteTorrent(com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate); if (findViewById(R.id.one_frame) != null) { popBackStackPhoneView(); } } } }); // Create dialog dialog = builder.create(); // Show dialog dialog.show(); } return true; case R.id.action_delete_drive: if (!isFinishing()) { builder = new Builder(this); // Message builder.setMessage(R.string.dm_deleteDriveTorrent).setTitle(R.string.dt_deleteDriveTorrent); // Cancel builder.setNeutralButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User canceled the dialog } }); // Ok builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User accepted the dialog if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate != null) { deleteDriveTorrent(com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate); if (findViewById(R.id.one_frame) != null) { popBackStackPhoneView(); } } } }); // Create dialog dialog = builder.create(); // Show dialog dialog.show(); } return true; case R.id.action_increase_prio: if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate != null) { increasePrioTorrent(com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate); // if (findViewById(R.id.one_frame) != null) { // popBackStackPhoneView(); // } } return true; case R.id.action_decrease_prio: if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate != null) { decreasePrioTorrent(com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate); // if (findViewById(R.id.one_frame) != null) { // popBackStackPhoneView(); // } } return true; case R.id.action_max_prio: if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate != null) { maxPrioTorrent(com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate); // if (findViewById(R.id.one_frame) != null) { // popBackStackPhoneView(); // } } return true; case R.id.action_min_prio: if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate != null) { minPrioTorrent(com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate); // if (findViewById(R.id.one_frame) != null) { // popBackStackPhoneView(); // } } return true; case R.id.action_resume_all: resumeAllTorrents(); return true; case R.id.action_pause_all: pauseAllTorrents(); return true; case R.id.action_upload_rate_limit: if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate != null) { uploadRateLimitDialog(com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate); // if (findViewById(R.id.one_frame) != null) { // popBackStackPhoneView(); // } } return true; case R.id.action_download_rate_limit: if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate != null) { downloadRateLimitDialog(com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate); // if (findViewById(R.id.one_frame) != null) { // popBackStackPhoneView(); // } } return true; case R.id.action_recheck: if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate != null) { recheckTorrents(com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate); // if (findViewById(R.id.one_frame) != null) { // popBackStackPhoneView(); // } } return true; case R.id.action_first_last_piece_prio: if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate != null) { toggleFirstLastPiecePrio(com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate); // if (findViewById(R.id.one_frame) != null) { // popBackStackPhoneView(); // } } return true; case R.id.action_sequential_download: if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate != null) { toggleSequentialDownload(com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate); // if (findViewById(R.id.one_frame) != null) { // popBackStackPhoneView(); // } } return true; case R.id.action_set_label: if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate != null) { setLabelDialog(com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate); // if (findViewById(R.id.one_frame) != null) { // popBackStackPhoneView(); // } } return true; case R.id.action_delete_label: if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate != null) { setLabel(com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate, " "); // if (findViewById(R.id.one_frame) != null) { // popBackStackPhoneView(); // } } return true; case R.id.action_toggle_alternative_rate: toggleAlternativeSpeedLimits(); refreshAfterCommand(2); swipeRefresh(); // if (findViewById(R.id.one_frame) != null) { // popBackStackPhoneView(); // } return true; case R.id.action_sortby_name: saveSortBy(SORTBY_NAME); invalidateOptionsMenu(); swipeRefresh(); return true; case R.id.action_sortby_size: saveSortBy(SORTBY_SIZE); invalidateOptionsMenu(); swipeRefresh(); return true; case R.id.action_sortby_eta: saveSortBy(SORTBY_ETA); invalidateOptionsMenu(); swipeRefresh(); return true; case R.id.action_sortby_priority: saveSortBy(SORTBY_PRIORITY); invalidateOptionsMenu(); swipeRefresh(); return true; case R.id.action_sortby_progress: saveSortBy(SORTBY_PROGRESS); invalidateOptionsMenu(); swipeRefresh(); return true; case R.id.action_sortby_ratio: saveSortBy(SORTBY_RATIO); invalidateOptionsMenu(); swipeRefresh(); return true; case R.id.action_sortby_downloadSpeed: saveSortBy(SORTBY_DOWNLOAD); invalidateOptionsMenu(); swipeRefresh(); return true; case R.id.action_sortby_uploadSpeed: saveSortBy(SORTBY_UPLOAD); invalidateOptionsMenu(); swipeRefresh(); return true; case R.id.action_sortby_added_on: saveSortBy(SORTBY_ADDEDON); invalidateOptionsMenu(); swipeRefresh(); return true; case R.id.action_sortby_completed_on: saveSortBy(SORTBY_COMPLETEDON); invalidateOptionsMenu(); swipeRefresh(); return true; case R.id.action_sortby_reverse_order: saveReverseOrder(!reverse_order); invalidateOptionsMenu(); swipeRefresh(); return true; case R.id.action_add_tracker: // Log.d("Debug", "Adding tracker"); if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate != null) { addUrlTracker(com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate); } return true; default: return super.onOptionsItemSelected(item); } } //Change current server protected void changeCurrentServer() { connection403ErrorCounter = 0; // Get values from preferences getSettings(); // redraw menu invalidateOptionsMenu(); // Get options from server and save them as shared preferences // locally // qBittorrentOptions qso = new qBittorrentOptions(); // qso.execute(new String[]{qbQueryString + "/preferences", "getSettings"}); // Save completedHashes sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); Editor editor = sharedPrefs.edit(); // Save hashes editor.putString("completed_hashes", ""); // Commit changes editor.apply(); canrefresh = true; refreshSwipeLayout(); // refreshCurrent(); // Get new token and cookie MainActivity.cookie = null; new qBittorrentApiTask().execute(new Intent()); // Log.d("Debug", "MainActivity - changeCurrentServer called"); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == SETTINGS_CODE) { // Log.d("Debug", "Notification alarm set"); alarmMgr = (AlarmManager) getApplication().getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(getApplication(), NotifierService.class); alarmIntent = PendingIntent.getBroadcast(getApplication(), 0, intent, 0); alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 5000, notification_period, alarmIntent); } if (requestCode == OPTION_CODE) { String json = ""; // Get Options getOptions(); /*************************************** * Save qBittorrent's options remotely * ****************************************/ // Maximum global number of simultaneous connections json += "\"max_connec\":" + global_max_num_connections; // Maximum number of simultaneous connections per torrent json += ",\"max_connec_per_torrent\":" + max_num_conn_per_torrent; // Global maximum number of upload slots: json += ",\"max_uploads\":" + max_uploads; // Maximum number of upload slots per torrent json += ",\"max_uploads_per_torrent\":" + max_num_upslots_per_torrent; // Global upload speed limit in KiB/s; -1 means no limit is applied json += ",\"up_limit\":" + global_upload; // Global download speed limit in KiB/s; -1 means no limit is // applied json += ",\"dl_limit\":" + global_download; // alternative global upload speed limit in KiB/s json += ",\"alt_up_limit\":" + alt_upload; // alternative global upload speed limit in KiB/s json += ",\"alt_dl_limit\":" + alt_download; // Is torrent queuing enabled ? json += ",\"queueing_enabled\":" + torrent_queueing; // Maximum number of active simultaneous downloads json += ",\"max_active_downloads\":" + max_act_downloads; // Maximum number of active simultaneous uploads json += ",\"max_active_uploads\":" + max_act_uploads; // Maximum number of active simultaneous downloads and uploads json += ",\"max_active_torrents\":" + max_act_torrents; // Schedule alternative rate limits json += ",\"scheduler_enabled\":" + schedule_alternative_rate_limits; // Scheduler starting hour json += ",\"schedule_from_hour\":" + alt_from_hour; // Scheduler starting min json += ",\"schedule_from_min\":" + alt_from_min; // Scheduler ending hour json += ",\"schedule_to_hour\":" + alt_to_hour; // Scheduler ending min json += ",\"schedule_to_min\":" + alt_to_min; // Scheduler scheduler days json += ",\"scheduler_days\":" + scheduler_days; // Log.d("Debug", "max_ratio_enabled:" + max_ratio_enabled); // Share Ratio Limiting json += ",\"max_ratio_enabled\":" + max_ratio_enabled; if (max_ratio_enabled == false) { json += ",\"max_ratio\":-1"; } else { json += ",\"max_ratio\":" + Float.parseFloat(max_ratio); } // String max_ratio_string = "4) max_ratio: " + Float.parseFloat(max_ratio); // Log.d("Debug", "3) max_ratio: " + Float.parseFloat(max_ratio)); // Log.d("Debug", max_ratio_string ); json += ",\"max_ratio_act\":" + max_ratio_act; // Put everything in an json object json = "{" + json + "}"; // Set preferences using this json object setQBittorrentPrefefrences(json); // Now it can be refreshed canrefresh = true; } if (requestCode == HELP_CODE && resultCode == RESULT_OK) { // Now it can be refreshed canrefresh = true; refreshSwipeLayout(); refreshCurrent(); } if (requestCode == SETTINGS_CODE && resultCode == RESULT_OK) { // Change current server (from settings or drawer menu) changeCurrentServer(); } if (requestCode == ADDFILE_CODE && resultCode == RESULT_OK) { String file_path_value = ""; // MaterialDesignPicker if (requestCode == ADDFILE_CODE && resultCode == RESULT_OK) { file_path_value = data.getStringExtra(FilePickerActivity.RESULT_FILE_PATH); } Log.d("Debug", "Torrent path: " + file_path_value); // Do something with the file path addTorrentFile(file_path_value); } } private void addUrlTorrent() { // get prompts.xml view LayoutInflater li = LayoutInflater.from(MainActivity.this); View addTorrentView = li.inflate(R.layout.add_torrent, null); // URL input final EditText urlInput = (EditText) addTorrentView.findViewById(R.id.url); if (!isFinishing()) { // Dialog Builder builder = new Builder(MainActivity.this); // Set add_torrent.xml to AlertDialog builder builder.setView(addTorrentView); // Cancel builder.setNeutralButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User cancelled the dialog } }); // Ok builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User accepted the dialog addTorrent(urlInput.getText().toString()); } }); // Create dialog AlertDialog dialog = builder.create(); // Show dialog dialog.show(); } } public void addUrlTracker(final String hash) { // get prompts.xml view LayoutInflater li = LayoutInflater.from(MainActivity.this); View addTrackerView = li.inflate(R.layout.add_tracker, null); // URL input final EditText urlInput = (EditText) addTrackerView.findViewById(R.id.url); if (!isFinishing()) { // Dialog Builder builder = new Builder(MainActivity.this); // Set add_torrent.xml to AlertDialog builder builder.setView(addTrackerView); // Cancel builder.setNeutralButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User cancelled the dialog // Log.d("Debug", "addUrlTracker - Cancelled"); } }); // Ok builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User accepted the dialog // Log.d("Debug", "addUrlTracker - Adding tracker"); addTracker(hash, urlInput.getText().toString()); } }); // Create dialog AlertDialog dialog = builder.create(); // Show dialog dialog.show(); } } protected void openSettings() { canrefresh = false; Intent intent = new Intent(getBaseContext(), com.lgallardo.qbittorrentclient.SettingsActivity.class); startActivityForResult(intent, SETTINGS_CODE); } protected void openHelp() { canrefresh = false; Intent intent = new Intent(getBaseContext(), HelpActivity.class); intent.putExtra("current", lastState); startActivityForResult(intent, HELP_CODE); } private void openOptions() { canrefresh = false; // Retrieve preferences for options Intent intent = new Intent(getBaseContext(), OptionsActivity.class); startActivityForResult(intent, OPTION_CODE); } // This get qBittorrent options to save them in shared preferences variables and then open the Option activity protected void getAndOpenOptions() { // Options - Execute the task in background toastText(R.string.getQBittorrentPrefefrences); qBittorrentOptions qso = new qBittorrentOptions(); qso.execute(new String[] { qbQueryString + "/preferences", "setOptions" }); } protected void getPRO() { Intent intent = new Intent(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=com.lgallardo.qbittorrentclientpro"))); startActivityForResult(intent, GETPRO_CODE); } public void startTorrent(String hash) { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "start", hash }); } public void startSelectedTorrents(String hashes) { // Execute the task in background String[] hashesArray = hashes.split("\\|"); for (int i = 0; hashesArray.length > i; i++) { qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "startSelected", hashesArray[i] }); } toastText(R.string.torrentsSelectedStarted); // Delay of 3 seconds refreshAfterCommand(3); } public void pauseTorrent(String hash) { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "pause", hash }); } public void pauseSelectedTorrents(String hashes) { // Execute the task in background String[] hashesArray = hashes.split("\\|"); for (int i = 0; hashesArray.length > i; i++) { qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "pauseSelected", hashesArray[i] }); } toastText(R.string.torrentsSelectedPaused); // Delay of 1 second refreshAfterCommand(1); } public void deleteTorrent(String hash) { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "delete", hash }); } public void deleteSelectedTorrents(String hashes) { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "deleteSelected", hashes }); toastText(R.string.torrentsSelectedDeleted); // Delay of 1 second refreshAfterCommand(1); } public void deleteDriveTorrent(String hash) { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "deleteDrive", hash }); } public void deleteDriveSelectedTorrents(String hashes) { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "deleteDriveSelected", hashes }); toastText(R.string.torrentsSelectedDeletedDrive); // Delay of 1 second refreshAfterCommand(1); } public void addTorrent(String url) { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "addTorrent", url }); } public void addTracker(String hash, String url) { // Execute the task in background // Log.d("Debug", "addTracker - Adding tracker"); qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "addTracker", hash + "&" + url }); } public void addTorrentFile(String url) { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "addTorrentFile", url }); } public void pauseAllTorrents() { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); if (qb_version.equals("3.2.x")) { qtc.execute(new String[] { "pauseAll", null }); } else { qtc.execute(new String[] { "pauseall", null }); } } public void resumeAllTorrents() { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); if (qb_version.equals("3.2.x")) { qtc.execute(new String[] { "resumeAll", null }); } else { qtc.execute(new String[] { "resumeall", null }); } } public void increasePrioTorrent(String hash) { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "increasePrio", hash }); } public void decreasePrioTorrent(String hash) { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "decreasePrio", hash }); } public void maxPrioTorrent(String hash) { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "maxPrio", hash }); } public void minPrioTorrent(String hash) { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "minPrio", hash }); } public void setFilePrio(String hash, int id, int priority) { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); hash = hash + "&" + id + "&" + priority; qtc.execute(new String[] { "setFilePrio", hash }); } public void recheckTorrents(String hashes) { // Execute the task in background String[] hashesArray = hashes.split("\\|"); for (int i = 0; hashesArray.length > i; i++) { qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "recheckSelected", hashesArray[i] }); } toastText(R.string.torrentsRecheck); // Delay of 3 seconds refreshAfterCommand(3); } public void toggleFirstLastPiecePrio(String hashes) { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "toggleFirstLastPiecePrio", hashes }); } public void toggleSequentialDownload(String hashes) { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "toggleSequentialDownload", hashes }); } public void setLabel(String hashes, String label) { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "setLabel", hashes + "&" + label }); } public void toggleAlternativeSpeedLimits() { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "toggleAlternativeSpeedLimits", "" }); } public void setQBittorrentPrefefrences(String hash) { // Execute the task in background qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "setQBittorrentPrefefrences", hash }); } public void uploadRateLimitDialog(final String hash) { // get prompts.xml view LayoutInflater li = LayoutInflater.from(MainActivity.this); View view = li.inflate(R.layout.upload_rate_limit, null); // URL input final EditText uploadRateLimit = (EditText) view.findViewById(R.id.upload_rate_limit); if (!isFinishing()) { // Dialog Builder builder = new Builder(MainActivity.this); // Set add_torrent.xml to AlertDialog builder builder.setView(view); // Cancel builder.setNeutralButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User cancelled the dialog } }); // Ok builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User accepted the dialog setUploadRateLimit(hash, uploadRateLimit.getText().toString()); } }); // Create dialog AlertDialog dialog = builder.create(); // Show dialog dialog.show(); } } public void setLabelDialog(final String hash) { // get prompts.xml view LayoutInflater li = LayoutInflater.from(MainActivity.this); View view = li.inflate(R.layout.set_label, null); // URL input final EditText label = (EditText) view.findViewById(R.id.set_label); if (!isFinishing()) { // Dialog Builder builder = new Builder(MainActivity.this); // Set add_torrent.xml to AlertDialog builder builder.setView(view); // Cancel builder.setNeutralButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User cancelled the dialog } }); // Ok builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User accepted the dialog String labelEncoded = Uri.encode(label.getText().toString()); setLabel(hash, labelEncoded); } }); // Create dialog AlertDialog dialog = builder.create(); // Show dialog dialog.show(); } } public void setUploadRateLimit(String hash, String uploadRateLimit) { int limit; if (uploadRateLimit != null && !uploadRateLimit.equals("")) { if (global_upload != null) { if (Integer.parseInt(global_upload) > 0) { limit = (Integer.parseInt(uploadRateLimit) > Integer.parseInt(global_upload) && Integer.parseInt(global_upload) != 0) ? Integer.parseInt(global_upload) : Integer.parseInt(uploadRateLimit); } else { limit = Integer.parseInt(uploadRateLimit); } String[] hashesArray = hash.split("\\|"); for (int i = 0; hashesArray.length > i; i++) { qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "setUploadRateLimit", hashesArray[i] + "&" + limit * 1024 }); } toastText(R.string.setUploadRateLimit); // Delay of 1 second refreshAfterCommand(1); } else { genericOkDialog(R.string.error, R.string.global_value_error); } } } public void setDownloadRateLimit(String hash, String downloadRateLimit) { int limit; if (downloadRateLimit != null && !downloadRateLimit.equals("")) { if (global_download != null) { if (Integer.parseInt(global_download) > 0) { limit = (Integer.parseInt(downloadRateLimit) > Integer.parseInt(global_download)) ? Integer.parseInt(global_download) : Integer.parseInt(downloadRateLimit); } else { limit = Integer.parseInt(downloadRateLimit); } String[] hashesArray = hash.split("\\|"); for (int i = 0; hashesArray.length > i; i++) { qBittorrentCommand qtc = new qBittorrentCommand(); qtc.execute(new String[] { "setDownloadRateLimit", hashesArray[i] + "&" + limit * 1024 }); } toastText(R.string.setDownloadRateLimit); // Delay of 1 second refreshAfterCommand(1); } else { genericOkDialog(R.string.error, R.string.global_value_error); } } } public void downloadRateLimitDialog(final String hash) { // get prompts.xml view LayoutInflater li = LayoutInflater.from(MainActivity.this); View view = li.inflate(R.layout.download_rate_limit, null); // URL input final EditText downloadRateLimit = (EditText) view.findViewById(R.id.download_rate_limit); if (!isFinishing()) { // Dialog Builder builder = new Builder(MainActivity.this); // Set add_torrent.xml to AlertDialog builder builder.setView(view); // Cancel builder.setNeutralButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User cancelled the dialog } }); // Ok builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User accepted the dialog setDownloadRateLimit(hash, downloadRateLimit.getText().toString()); } }); // Create dialog AlertDialog dialog = builder.create(); // Show dialog dialog.show(); } } public void refreshAfterCommand(int delay) { // switch (drawerList.getCheckedItemPosition()) { switch (actionStates.indexOf(currentState)) { case 0: refreshWithDelay("all", currentLabel, delay); break; case 1: refreshWithDelay("downloading", currentLabel, delay); break; case 2: refreshWithDelay("completed", currentLabel, delay); break; case 3: refreshWithDelay("seeding", currentLabel, delay); break; case 4: refreshWithDelay("pause", currentLabel, delay); break; case 5: refreshWithDelay("active", currentLabel, delay); break; case 6: refreshWithDelay("inactive", currentLabel, delay); break; case 7: break; case 8: break; default: refreshWithDelay("all", currentLabel, delay); break; } } public void genericOkDialog(int title, int message) { genericOkDialog(title, message, null); } public void genericOkDialog(int message, DialogInterface.OnClickListener okListener) { genericOkDialog(-1, message, okListener); } public void genericOkDialog(int message) { genericOkDialog(-1, message, null); } public void genericOkDialog(int title, int message, DialogInterface.OnClickListener okListener) { if (!isFinishing()) { Builder builder = new Builder(this); // Title if (title != -1) { builder.setTitle(title); } // Message builder.setMessage(message); // Ok builder.setPositiveButton(R.string.ok, okListener); // Create dialog AlertDialog dialog = builder.create(); // Show dialog dialog.show(); } } private void genericOkCancelDialog(int title, int message) { genericOkCancelDialog(title, message, null); } private void genericOkCancelDialog(int message, DialogInterface.OnClickListener okListener) { genericOkCancelDialog(-1, message, okListener); } private void genericOkCancelDialog(int message) { genericOkCancelDialog(-1, message, null); } private void genericOkCancelDialog(int title, int message, DialogInterface.OnClickListener okListener) { if (!isFinishing()) { Builder builder = new Builder(this); // Title if (title != -1) { builder.setTitle(title); } // Message builder.setMessage(message); // Ok builder.setPositiveButton(R.string.ok, okListener); // Cancel builder.setNegativeButton(R.string.cancel, null); // Create dialog AlertDialog dialog = builder.create(); // Show dialog dialog.show(); } } public void qBittorrentNoSettingsFoundDialog(int title, int message) { if (!isFinishing()) { Builder builder = new Builder(this); // Message builder.setMessage(message).setTitle(title); // Ok builder.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User accepted the dialog } }); // Settings builder.setPositiveButton(R.string.settings, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User accepted the dialog openSettings(); } }); // Create dialog AlertDialog dialog = builder.create(); // Show dialog dialog.show(); } } // Delay method public void refreshWithDelay(final String state, final String label, int seconds) { seconds *= 1000; final Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { // Do something after 5s = 5000ms refresh(state, label); } }, seconds); } // Get settings protected void getSettings() { // Preferences stuff sharedPrefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); builderPrefs = new StringBuilder(); builderPrefs.append("\n" + sharedPrefs.getString("language", "NULL")); // Get values from preferences currentServer = sharedPrefs.getString("currentServer", "1"); hostname = sharedPrefs.getString("hostname", ""); subfolder = sharedPrefs.getString("subfolder", ""); protocol = sharedPrefs.getString("protocol", "NULL"); // If user leave the field empty, set 8080 port try { port = Integer.parseInt(sharedPrefs.getString("port", "8080")); } catch (NumberFormatException e) { port = 8080; } username = sharedPrefs.getString("username", "NULL"); password = sharedPrefs.getString("password", "NULL"); https = sharedPrefs.getBoolean("https", false); // Check https if (https) { protocol = "https"; } else { protocol = "http"; } // Get refresh info auto_refresh = sharedPrefs.getBoolean("auto_refresh", true); try { refresh_period = Integer.parseInt(sharedPrefs.getString("refresh_period", "120000")); } catch (NumberFormatException e) { refresh_period = 120000; } // Get connection and data timeouts try { connection_timeout = Integer.parseInt(sharedPrefs.getString("connection_timeout", "10")); // New default value to make it work with qBittorrent 3.2.x if (connection_timeout < 10) { connection_timeout = 10; } } catch (NumberFormatException e) { connection_timeout = 10; } try { data_timeout = Integer.parseInt(sharedPrefs.getString("data_timeout", "20")); // New default value to make it work with qBittorrent 3.2.x if (data_timeout < 20) { data_timeout = 20; } } catch (NumberFormatException e) { data_timeout = 20; } sortby_value = sharedPrefs.getInt("sortby_value", 1); reverse_order = sharedPrefs.getBoolean("reverse_order", false); dark_ui = sharedPrefs.getBoolean("dark_ui", false); qb_version = sharedPrefs.getString("qb_version", "3.2.x"); MainActivity.cookie = sharedPrefs.getString("qbCookie", null); // Get last state lastState = sharedPrefs.getString("lastState", "all"); // Get last label // lastLabel = sharedPrefs.getString("lastLabel", "all"); lastLabel = sharedPrefs.getString("lastLabel", "all"); currentLabel = lastLabel; // Notification check enable_notifications = sharedPrefs.getBoolean("enable_notifications", false); try { notification_period = Long.parseLong(sharedPrefs.getString("notification_period", "120000L")); } catch (NumberFormatException e) { notification_period = 120000L; } header = sharedPrefs.getBoolean("header", true); // Get package info PackageInfo pInfo = null; try { pInfo = getPackageManager().getPackageInfo(getPackageName(), 0); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } // Get package name packageName = pInfo.packageName; packageVersion = pInfo.versionName; // Get AlternativeSpeedLimitsEnabled value alternative_speeds = sharedPrefs.getBoolean("alternativeSpeedLimitsEnabled", false); // Get local SSID properties ssid = sharedPrefs.getString("ssid", ""); local_hostname = sharedPrefs.getString("local_hostname", null); // If user leave the field empty, set 8080 port try { local_port = Integer.parseInt(sharedPrefs.getString("local_port", "-1")); } catch (NumberFormatException e) { local_port = -1; } // Set SSI and local hostname and port if (ssid != null && !ssid.equals("")) { // Get SSID if WiFi WifiManager wifiMgr = (WifiManager) getSystemService(Context.WIFI_SERVICE); WifiInfo wifiInfo = wifiMgr.getConnectionInfo(); String wifiSSID = wifiInfo.getSSID(); // Log.d("Debug", "WiFi SSID: " + wifiSSID); // Log.d("Debug", "SSID: " + ssid); if (wifiSSID.toUpperCase().equals("\"" + ssid.toUpperCase() + "\"") && wifiMgr.getWifiState() == WifiManager.WIFI_STATE_ENABLED) { if (local_hostname != null && !local_hostname.equals("")) { hostname = local_hostname; } if (local_port != -1) { port = local_port; } // Log.d("Debug", "hostname: " + hostname); // Log.d("Debug", "port: " + port); // Log.d("Debug", "local_hostname: " + local_hostname); // Log.d("Debug", "local_port: " + local_port); } } // Get keystore for self-signed certificate keystore_path = sharedPrefs.getString("keystore_path" + currentServer, ""); keystore_password = sharedPrefs.getString("keystore_password" + currentServer, ""); } // Get Options protected void getOptions() { // Preferences stuff sharedPrefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); builderPrefs = new StringBuilder(); builderPrefs.append("\n" + sharedPrefs.getString("language", "NULL")); // Get values from options global_max_num_connections = sharedPrefs.getString("global_max_num_connections", "0"); max_num_conn_per_torrent = sharedPrefs.getString("max_num_conn_per_torrent", "0"); max_uploads = sharedPrefs.getString("max_uploads", "0"); max_num_upslots_per_torrent = sharedPrefs.getString("max_num_upslots_per_torrent", "0"); global_upload = sharedPrefs.getString("global_upload", "0"); global_download = sharedPrefs.getString("global_download", "0"); alt_upload = sharedPrefs.getString("alt_upload", "0"); alt_download = sharedPrefs.getString("alt_download", "0"); // This will used for checking if the torrent queuing option are used torrent_queueing = sharedPrefs.getBoolean("torrent_queueing", false); max_act_downloads = sharedPrefs.getString("max_act_downloads", "0"); max_act_uploads = sharedPrefs.getString("max_act_uploads", "0"); max_act_torrents = sharedPrefs.getString("max_act_torrents", "0"); schedule_alternative_rate_limits = sharedPrefs.getBoolean("schedule_alternative_rate_limits", false); alt_from_hour = "" + TimePreference.getHour(sharedPrefs.getString("alt_from", "8:00")); alt_from_min = "" + TimePreference.getMinute(sharedPrefs.getString("alt_from", "8:00")); alt_to_hour = "" + TimePreference.getHour(sharedPrefs.getString("alt_to", "20:00")); alt_to_min = "" + TimePreference.getMinute(sharedPrefs.getString("alt_to", "20:00")); scheduler_days = sharedPrefs.getString("scheduler_days", "NULL"); // Check alternatives speed alternative_speeds = sharedPrefs.getBoolean("alternativeSpeedLimitsEnabled", false); // Share Ratio Limiting max_ratio_enabled = sharedPrefs.getBoolean("max_ratio_enabled", false); max_ratio = sharedPrefs.getString("max_ratio", "0"); max_ratio_act = sharedPrefs.getString("max_ratio_act", "NULL"); } protected void notifyCompleted(HashMap completedTorrents) { Intent intent = new Intent(this, MainActivity.class); PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0); // build notification // the addAction re-use the same intent to keep the example short Notification.Builder builder = new Notification.Builder(this).setContentTitle("qBittorrent") .setContentText("Torrent(s) completed").setSmallIcon(R.drawable.ic_stat_completed) .setNumber(completedTorrents.size()).setContentIntent(pIntent).setAutoCancel(true); NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); Notification notification; notification = builder.getNotification(); notificationManager.notify(0, notification); } private void saveLastState(String state) { currentState = state; savePreferenceAsString("lastState", state); } public void saveLastLabel(String label) { currentLabel = label; savePreferenceAsString("lastLabel", label); } private void saveSortBy(int sortby_value) { MainActivity.sortby_value = sortby_value; savePreferenceAsInt("sortby_value", sortby_value); } // Save key-value preference as String private void savePreferenceAsString(String preference, String value) { // Save preference locally sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); Editor editor = sharedPrefs.edit(); // Save key-values editor.putString(preference, value); // Commit changes editor.apply(); } // Save key-value preference as Int private void savePreferenceAsInt(String preference, int value) { // Save preference locally sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); Editor editor = sharedPrefs.edit(); // Save key-values editor.putInt(preference, value); // Commit changes editor.apply(); } // Save key-value preference as boolean private void savePreferenceAsBoolean(String preference, boolean value) { // Save preference locally sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); Editor editor = sharedPrefs.edit(); // Save key-values editor.putBoolean(preference, value); // Commit changes editor.apply(); } private void saveReverseOrder(boolean reverse_order) { MainActivity.reverse_order = reverse_order; // Save options locally sharedPrefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); Editor editor = sharedPrefs.edit(); // Save key-values editor.putBoolean("reverse_order", reverse_order); // Commit changes editor.apply(); } private void selectItem(int position) { if (findViewById(R.id.one_frame) != null) { FragmentManager fragmentManager = getFragmentManager(); if (fragmentManager.findFragmentByTag( "firstFragment") instanceof com.lgallardo.qbittorrentclient.TorrentDetailsFragment) { // Reset back button stack for (int i = 0; i < fragmentManager.getBackStackEntryCount(); ++i) { fragmentManager.popBackStack(); } } } } @Override public void swipeRefresh() { if (hostname.equals("")) { qBittorrentNoSettingsFoundDialog(R.string.info, R.string.about_help1); disableRefreshSwipeLayout(); } else { // Set the refresh layout (refresh icon, etc) refreshSwipeLayout(); // Actually refresh data refreshCurrent(); // Load banner loadBanner(); } } public static void disableRefreshSwipeLayout() { if (com.lgallardo.qbittorrentclient.AboutFragment.mSwipeRefreshLayout != null) { com.lgallardo.qbittorrentclient.AboutFragment.mSwipeRefreshLayout.setRefreshing(false); com.lgallardo.qbittorrentclient.AboutFragment.mSwipeRefreshLayout.clearAnimation(); com.lgallardo.qbittorrentclient.AboutFragment.mSwipeRefreshLayout.setEnabled(true); } if (com.lgallardo.qbittorrentclient.ItemstFragment.mSwipeRefreshLayout != null) { com.lgallardo.qbittorrentclient.ItemstFragment.mSwipeRefreshLayout.setRefreshing(false); com.lgallardo.qbittorrentclient.ItemstFragment.mSwipeRefreshLayout.clearAnimation(); com.lgallardo.qbittorrentclient.ItemstFragment.mSwipeRefreshLayout.setEnabled(true); } if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.mSwipeRefreshLayout != null) { com.lgallardo.qbittorrentclient.TorrentDetailsFragment.mSwipeRefreshLayout.setRefreshing(false); com.lgallardo.qbittorrentclient.TorrentDetailsFragment.mSwipeRefreshLayout.clearAnimation(); com.lgallardo.qbittorrentclient.TorrentDetailsFragment.mSwipeRefreshLayout.setEnabled(true); } listViewRefreshing = false; } public void refreshSwipeLayout() { if (!hostname.equals("")) { listViewRefreshing = true; if (AboutFragment.mSwipeRefreshLayout != null) { AboutFragment.mSwipeRefreshLayout.setRefreshing(true); } if (com.lgallardo.qbittorrentclient.ItemstFragment.mSwipeRefreshLayout != null) { com.lgallardo.qbittorrentclient.ItemstFragment.mSwipeRefreshLayout.setRefreshing(true); com.lgallardo.qbittorrentclient.ItemstFragment.mSwipeRefreshLayout.setEnabled(false); } if (com.lgallardo.qbittorrentclient.TorrentDetailsFragment.mSwipeRefreshLayout != null) { com.lgallardo.qbittorrentclient.TorrentDetailsFragment.mSwipeRefreshLayout.setRefreshing(true); } } } private void openFilePicker() { // Check Dangerous permissions (Android 6.0+, API 23+) if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { genericOkDialog(R.string.error_permission2, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ActivityCompat.requestPermissions(MainActivity.this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }, MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE); } }); } else { // No explanation needed, request the permission. ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }, MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE); } } else { // Permissions granted, open file picker Intent intent = new Intent(getApplicationContext(), FilePickerActivity.class); intent.putExtra(FilePickerActivity.ARG_FILE_FILTER, Pattern.compile(".*\\.torrent")); // startActivityForResult(INTENT, RESULT_CODE); startActivityForResult(intent, ADDFILE_CODE); } } // Here is where the action happens private class qBittorrentCookieTask extends AsyncTask<String, Integer, String[]> { @Override protected String[] doInBackground(String... params) { // Get values from preferences getSettings(); // Creating new JSON Parser com.lgallardo.qbittorrentclient.JSONParser jParser = new com.lgallardo.qbittorrentclient.JSONParser( hostname, subfolder, protocol, port, keystore_path, keystore_password, username, password, connection_timeout, data_timeout); String newCookie = ""; String api = ""; try { newCookie = jParser.getNewCookie(); } catch (JSONParserStatusCodeException e) { httpStatusCode = e.getCode(); } if (newCookie == null) { newCookie = ""; } if (api == null) { api = ""; } return new String[] { newCookie, api }; } @Override protected void onPostExecute(String[] result) { MainActivity.cookie = result[0]; // Save cookie savePreferenceAsString("qbCookie", result[0]); // Execute the task in background qbTask = new qBittorrentTask().execute(params); } } // Here is where the action happens private class qBittorrentApiTask extends AsyncTask<Intent, Integer, String[]> { @Override protected String[] doInBackground(Intent... intents) { // Get values from preferences getSettings(); // Creating new JSON Parser com.lgallardo.qbittorrentclient.JSONParser jParser = new com.lgallardo.qbittorrentclient.JSONParser( hostname, subfolder, protocol, port, keystore_path, keystore_password, username, password, connection_timeout, data_timeout); String apiVersion = ""; httpStatusCode = 0; // Try to get the API number try { apiVersion = jParser.getApi(); qb_api = apiVersion; qbittorrentServer = apiVersion; // Log.d("Debug", "API: " + apiVersion); } catch (JSONParserStatusCodeException e) { qb_api = "0"; httpStatusCode = e.getCode(); Log.d("Debug", "API Exception: " + httpStatusCode); } // If < 3.2.x, get qBittorrent version if (httpStatusCode > 200 || apiVersion == null) { try { apiVersion = jParser.getVersion(); qbittorrentServer = apiVersion; } catch (JSONParserStatusCodeException e) { httpStatusCode = e.getCode(); } } return new String[] { apiVersion, intents[0].getStringExtra("currentState") }; } @Override protected void onPostExecute(String[] result) { String apiVersion = result[0]; int api = 0; try { api = Integer.parseInt(apiVersion); } catch (Exception e) { api = 0; } if (apiVersion != null && (api > 1 || apiVersion.contains("3.2") || apiVersion.contains("3.3"))) { qb_version = "3.2.x"; // Get new cookie cookie = null; } else if (apiVersion.contains("3.1")) { qb_version = "3.1.x"; } else { qb_version = "2.x"; } // Save version savePreferenceAsString("qb_version", qb_version); // Refresh String stateBefore = result[1]; if (stateBefore != null) { // Set selection according to last state setSelectionAndTitle(stateBefore); // Set the refresh layout (refresh icon, etc) refreshSwipeLayout(); // Refresh state refresh(stateBefore, ""); // load banner loadBanner(); } else { swipeRefresh(); } } } // Here is where the action happens private class qBittorrentCommand extends AsyncTask<String, Integer, String[]> { @Override protected String[] doInBackground(String... params) { String result = ""; // Get values from preferences getSettings(); // Creating new JSON Parser com.lgallardo.qbittorrentclient.JSONParser jParser = new com.lgallardo.qbittorrentclient.JSONParser( hostname, subfolder, protocol, port, keystore_path, keystore_password, username, password, connection_timeout, data_timeout); jParser.setCookie(cookie); try { httpStatusCode = 0; // Validate setLabel for API 10+ try { if (Integer.parseInt(MainActivity.qb_api) >= 10 && "setLabel".equals(params[0])) { params[0] = "setCategory"; // Log.d("Debug", params[0]); } } catch (NumberFormatException e) { Log.e("Debug", e.toString()); } result = jParser.postCommand(params[0], params[1]); } catch (JSONParserStatusCodeException e) { httpStatusCode = e.getCode(); } return (new String[] { params[0], result }); } @Override protected void onPostExecute(String[] results) { String command = results[0]; String result = results[1]; // Handle HTTP status code if (httpStatusCode == 1) { toastText(R.string.error1); httpStatusCode = 0; return; } if (httpStatusCode == 2) { toastText(R.string.error2); toast.show(); httpStatusCode = 0; return; } if (httpStatusCode == 401) { toastText(R.string.error401); httpStatusCode = 0; return; } if (httpStatusCode == 403 || httpStatusCode == 404) { if (qb_version.equals("3.2.x")) { cookie = null; } connection403ErrorCounter = connection403ErrorCounter + 1; if (connection403ErrorCounter > 1) { if (cookie != null && !cookie.equals("")) { // Only toasts the message if there is not a cookie set before toastText(R.string.error403); cookie = null; } httpStatusCode = 0; disableRefreshSwipeLayout(); } httpStatusCode = 0; return; } // This delay is needed for postCommaresume action. Other actions have a // fewer delay (1 second). int delay = 1; int messageId = R.string.connection_error; if (command == null) { messageId = R.string.connection_error; } if ("start".equals(command)) { messageId = R.string.torrentStarted; // Needed to refresh after a resume and see the change delay = 3; } if ("pause".equals(command)) { messageId = R.string.torrentPaused; delay = 3; } if ("delete".equals(command)) { messageId = R.string.torrentDeleted; } if ("deleteDrive".equals(command)) { messageId = R.string.torrentDeletedDrive; } if ("addTorrent".equals(command)) { messageId = R.string.torrentAdded; } if ("addTorrentFile".equals(command)) { messageId = R.string.torrentFileAdded; } if ("addTracker".equals(command)) { messageId = R.string.torrentsApplyingChange; delay = 3; } if ("pauseAll".equals(command)) { messageId = R.string.AllTorrentsPaused; } if ("resumeAll".equals(command)) { messageId = R.string.AllTorrentsResumed; // Needed to refresh after a "resume all" and see the changes delay = 3; } if ("increasePrio".equals(command)) { messageId = R.string.increasePrioTorrent; delay = 3; } if ("decreasePrio".equals(command)) { messageId = R.string.decreasePrioTorrent; delay = 3; } if ("maxPrio".equals(command)) { messageId = R.string.priorityUpdated; delay = 3; } if ("minPrio".equals(command)) { messageId = R.string.priorityUpdated; delay = 3; } if ("setFilePrio".equals(command)) { messageId = R.string.priorityUpdated; } if ("setQBittorrentPrefefrences".equals(command)) { messageId = R.string.setQBittorrentPrefefrences; } if ("setUploadRateLimit".equals(command)) { messageId = R.string.setUploadRateLimit; // if (findViewById(R.id.one_frame) != null) { // popBackStackPhoneView(); // } } if ("setDownloadRateLimit".equals(command)) { messageId = R.string.setDownloadRateLimit; // if (findViewById(R.id.one_frame) != null) { // popBackStackPhoneView(); // } } if ("recheckSelected".equals(command)) { messageId = R.string.torrentsRecheck; } if ("toggleFirstLastPiecePrio".equals(command)) { messageId = R.string.torrentstogglefisrtLastPiecePrio; } if ("toggleSequentialDownload".equals(command)) { messageId = R.string.torrentstoggleSequentialDownload; } if ("toggleAlternativeSpeedLimits".equals(command)) { messageId = R.string.toggledAlternativeRates; } if ("setLabel".equals(command) || "setCategory".equals(command)) { messageId = R.string.torrentsApplyingChange; delay = 3; } if ("alternativeSpeedLimitsEnabled".equals(command)) { try { if ("1".equals(result) == true) { savePreferenceAsBoolean("alternativeSpeedLimitsEnabled", true); altSpeedLimitsMenuItem.setEnabled(true); altSpeedLimitsMenuItem.setChecked(true); } // Here an else cannot be used, because result can be "" if ("0".equals(result) == true) { savePreferenceAsBoolean("alternativeSpeedLimitsEnabled", false); altSpeedLimitsMenuItem.setEnabled(true); altSpeedLimitsMenuItem.setChecked(false); } } catch (Exception e) { } // Log.d("Debug", "alternativeSpeedLimitsEnabled: " + result); } if (!("startSelected".equals(command)) && !("pauseSelected".equals(command)) && !("deleteSelected".equals(command)) && !("deleteDriveSelected".equals(command)) && !("setUploadRateLimit".equals(command)) && !("setDownloadRateLimit".equals(command)) && !("recheckSelected".equals(command)) && !("alternativeSpeedLimitsEnabled".equals(command))) { toastText(messageId); // Refresh refreshAfterCommand(delay); } } } // Here is where the action happens private class qBittorrentTask extends AsyncTask<String, Integer, Torrent[]> { @Override protected Torrent[] doInBackground(String... params) { String name, size, info, progress, state, hash, ratio, leechs, seeds, priority, eta, uploadSpeed, downloadSpeed, addedOn, completionOn, label; boolean sequentialDownload = false; boolean firstLastPiecePrio = false; Torrent[] torrents = null; // Get settings getSettings(); try { // Creating new JSON Parser jParser = new com.lgallardo.qbittorrentclient.JSONParser(hostname, subfolder, protocol, port, keystore_path, keystore_password, username, password, connection_timeout, data_timeout); jParser.setCookie(MainActivity.cookie); JSONArray jArray = jParser.getJSONArrayFromUrl(params[0]); if (jArray != null) { torrents = new Torrent[jArray.length()]; MainActivity.names = new String[jArray.length()]; for (int i = 0; i < jArray.length(); i++) { JSONObject json = jArray.getJSONObject(i); name = json.getString(TAG_NAME); size = json.getString(TAG_SIZE).replace(",", "."); progress = String.format("%.2f", json.getDouble(TAG_PROGRESS) * 100) + "%"; progress = progress.replace(",", "."); info = ""; state = json.getString(TAG_STATE); hash = json.getString(TAG_HASH); ratio = json.getString(TAG_RATIO).replace(",", "."); leechs = json.getString(TAG_NUMLEECHS); seeds = json.getString(TAG_NUMSEEDS); priority = json.getString(TAG_PRIORITY); eta = json.getString(TAG_ETA); downloadSpeed = json.getString(TAG_DLSPEED); uploadSpeed = json.getString(TAG_UPSPEED); try { addedOn = json.getString(TAG_ADDEDON); } catch (JSONException je) { addedOn = null; } try { completionOn = json.getString(TAG_COMPLETIONON); } catch (JSONException je) { completionOn = null; } try { if (Integer.parseInt(MainActivity.qb_api) < 10) { label = json.getString(TAG_LABEL); } else { label = json.getString(TAG_CATEGORY); } } catch (JSONException je) { label = null; } if (qb_version.equals("3.2.x")) { size = Common.calculateSize(size); eta = Common.secondsToEta(eta); downloadSpeed = Common.calculateSize(downloadSpeed) + "/s"; uploadSpeed = Common.calculateSize(uploadSpeed) + "/s"; try { sequentialDownload = json.getBoolean(TAG_SEQDL); } catch (Exception e) { sequentialDownload = false; } try { firstLastPiecePrio = json.getBoolean(TAG_FLPIECEPRIO); } catch (Exception e) { firstLastPiecePrio = false; } } torrents[i] = new Torrent(name, size, state, hash, info, ratio, progress, leechs, seeds, priority, eta, downloadSpeed, uploadSpeed, sequentialDownload, firstLastPiecePrio, addedOn, completionOn, label); MainActivity.names[i] = name; // Get torrent generic properties try { // Calculate total downloaded Double sizeScalar = Double.parseDouble(size.substring(0, size.indexOf(" "))); String sizeUnit = size.substring(size.indexOf(" "), size.length()); torrents[i] .setDownloaded(String.format("%.1f", sizeScalar * json.getDouble(TAG_PROGRESS)) .replace(",", ".") + sizeUnit); } catch (Exception e) { torrents[i].setDownloaded(size); } String infoString = ""; if (packageName.equals("com.lgallardo.qbittorrentclient")) { // Info free infoString = torrents[i].getDownloaded() + " / " + torrents[i].getSize() + " " + Character.toString('\u2193') + " " + torrents[i].getDownloadSpeed() + " " + Character.toString('\u2191') + " " + torrents[i].getUploadSpeed() + " " + Character.toString('\u2022') + " " + torrents[i].getRatio() + " " + Character.toString('\u2022') + " " + progress + " " + Character.toString('\u2022') + " " + torrents[i].getEta(); if (torrents[i].getLabel() != null && !torrents[i].getLabel().equals("")) { infoString = infoString + " " + Character.toString('\u2022') + " " + torrents[i].getLabel(); } } else { // Info pro infoString = torrents[i].getDownloaded() + " / " + torrents[i].getSize() + " " + Character.toString('\u2193') + " " + torrents[i].getDownloadSpeed() + " " + Character.toString('\u2191') + " " + torrents[i].getUploadSpeed() + " " + Character.toString('\u2022') + " " + torrents[i].getRatio() + " " + Character.toString('\u2022') + " " + torrents[i].getEta(); if (torrents[i].getLabel() != null && !torrents[i].getLabel().equals("")) { infoString = infoString + " " + Character.toString('\u2022') + " " + torrents[i].getLabel(); } } // Set info torrents[i].setInfo(infoString); } } } catch (JSONParserStatusCodeException e) { httpStatusCode = e.getCode(); torrents = null; Log.e("JSONParserStatusCode", e.toString()); if (CustomLogger.isMainActivityReporting()) { CustomLogger.saveReportMessage("Main", "[qBittorrentTask - JSONParserStatusCode]: " + e.toString()); } } catch (Exception e) { torrents = null; Log.e("MAIN:", e.toString()); if (CustomLogger.isMainActivityReporting()) { CustomLogger.saveReportMessage("Main", "[qBittorrentTask - Exception]: " + e.toString()); } } return torrents; } @Override protected void onPostExecute(Torrent[] result) { if (result == null) { // Reporting if (CustomLogger.isMainActivityReporting()) { CustomLogger.saveReportMessage("Main", "qBittorrentTask - result is null"); CustomLogger.saveReportMessage("Main", "qBittorrentTask - httpStatusCode: " + httpStatusCode); } // Handle HTTP status code if (httpStatusCode == 1) { toastText(R.string.error1); httpStatusCode = 0; } if (httpStatusCode == 2) { toastText(R.string.error2); httpStatusCode = 0; } if (httpStatusCode == 401) { toastText(R.string.error401); // Get new Cookie if (qb_version.equals("3.2.x")) { cookie = null; } httpStatusCode = 0; } if (httpStatusCode == 400) { toastText(R.string.connection_error); // Get new Cookie if (qb_version.equals("3.2.x")) { cookie = null; } httpStatusCode = 0; return; } if (httpStatusCode == 403 || httpStatusCode == 404) { // Log.d("Debug","MainActivity - refresh - qb_version:" +qb_version ); // Get new Cookie if (qb_version.equals("3.2.x")) { connection403ErrorCounter = connection403ErrorCounter + 1; if (connection403ErrorCounter > 1) { if (cookie != null && !cookie.equals("")) { // Only toasts the message if there is not a cookie set before toastText(R.string.error403); } cookie = null; httpStatusCode = 0; disableRefreshSwipeLayout(); } else { // Ask a new cookie and re-execute the task in background new qBittorrentCookieTask().execute(params); } } } } else { // Reporting if (CustomLogger.isMainActivityReporting()) { CustomLogger.saveReportMessage("Main", "qBittorrentTask - result length: " + result.length); CustomLogger.saveReportMessage("Main", "qBittorrentTask - httpStatusCode: " + httpStatusCode); } connection403ErrorCounter = 0; ArrayList<Torrent> torrentsFiltered = new ArrayList<Torrent>(); // Labels String label = null; // Log.d("Debug", "Still looking for..."+searchField); for (int i = 0; i < result.length; i++) { // Get label label = result[i].getLabel(); if (!labels.contains(label)) { // Add Label labels.add(label); // Log.d("Debug", "Label: " + label); } if (params[1].equals("all") && (searchField == "" || result[i].getFile().toUpperCase().contains(searchField.toUpperCase()))) { torrentsFiltered.add(result[i]); } if (params[1].equals("downloading") && (searchField == "" || result[i].getFile().toUpperCase().contains(searchField.toUpperCase()))) { if ("downloading".equals(result[i].getState()) || "stalledDL".equals(result[i].getState()) || "pausedDL".equals(result[i].getState()) || "queuedDL".equals(result[i].getState()) || "checkingDL".equals(result[i].getState())) { torrentsFiltered.add(result[i]); } } if (params[1].equals("completed") && (searchField == "" || result[i].getFile().toUpperCase().contains(searchField.toUpperCase()))) { if ("uploading".equals(result[i].getState()) || "stalledUP".equals(result[i].getState()) || "pausedUP".equals(result[i].getState()) || "queuedUP".equals(result[i].getState()) || "checkingUP".equals(result[i].getState()) || "forcedUP".equals(result[i].getState())) { torrentsFiltered.add(result[i]); } } if (params[1].equals("seeding") && (searchField == "" || result[i].getFile().toUpperCase().contains(searchField.toUpperCase()))) { if ("uploading".equals(result[i].getState()) || "stalledUP".equals(result[i].getState()) || "forcedUP".equals(result[i].getState())) { torrentsFiltered.add(result[i]); } } if (params[1].equals("pause") && (searchField == "" || result[i].getFile().toUpperCase().contains(searchField.toUpperCase()))) { if ("pausedDL".equals(result[i].getState()) || "pausedUP".equals(result[i].getState())) { torrentsFiltered.add(result[i]); } } if (params[1].equals("active") && (searchField == "" || result[i].getFile().toUpperCase().contains(searchField.toUpperCase()))) { if ("uploading".equals(result[i].getState()) || "downloading".equals(result[i].getState())) { torrentsFiltered.add(result[i]); } } if (params[1].equals("inactive") && (searchField == "" || result[i].getFile().toUpperCase().contains(searchField.toUpperCase()))) { if ("pausedUP".equals(result[i].getState()) || "pausedDL".equals(result[i].getState()) || "queueUP".equals(result[i].getState()) || "queueDL".equals(result[i].getState()) || "stalledUP".equals(result[i].getState()) || "stalledDL".equals(result[i].getState())) { torrentsFiltered.add(result[i]); } } } // Labels ArrayList<DrawerItem> labelItems = new ArrayList<DrawerItem>(); // Set unlabeled first // Add label category labelItems.add(new DrawerItem(R.drawable.ic_drawer_labels, getResources().getString(R.string.drawer_label_labels), DRAWER_LABEL_CATEGORY, true, "labelCategory")); // Add All label = getResources().getString(R.string.drawer_label_all); // Log.d("Debug", "labes.size(): " + labels.size()); labelItems.add(new DrawerItem(R.drawable.ic_drawer_subitem, label, DRAWER_LABEL, (currentLabel.equals(label) || !labels.contains(currentLabel) && !currentLabel.equals(getResources().getString(R.string.drawer_label_unlabeled))), "label")); // Add unlabeled label = getResources().getString(R.string.drawer_label_unlabeled); labelItems.add(new DrawerItem(R.drawable.ic_drawer_subitem, label, DRAWER_LABEL, currentLabel.equals(label) || currentLabel.equals(""), "label")); // Log.d("Debug", "currentLabel: " + currentLabel); if (labels != null) { // Sort labels Collections.sort(labels); for (int i = 0; i < labels.size(); i++) { label = labels.get(i); if (label != null && !label.equals("")) { labelItems.add(new DrawerItem(R.drawable.ic_drawer_subitem, label, DRAWER_LABEL, currentLabel.equals(label), "label")); } } rAdapter.refreshDrawerLabels(labelItems); } // Sort by filename if (sortby_value == SORTBY_NAME) { Collections.sort(torrentsFiltered, new TorrentNameComparator(reverse_order)); } // Sort by size if (sortby_value == SORTBY_SIZE) { Collections.sort(torrentsFiltered, new TorrentSizeComparator(reverse_order)); } // Sort by Eta if (sortby_value == SORTBY_ETA) { Collections.sort(torrentsFiltered, new TorrentEtaComparator(reverse_order)); } // Sort by priority if (sortby_value == SORTBY_PRIORITY) { Collections.sort(torrentsFiltered, new TorrentPriorityComparator(reverse_order)); } // Sort by progress if (sortby_value == SORTBY_PROGRESS) { Collections.sort(torrentsFiltered, new TorrentProgressComparator(reverse_order)); } // Sort by Ratio if (sortby_value == SORTBY_RATIO) { Collections.sort(torrentsFiltered, new TorrentRatioComparator(reverse_order)); } // Sort by download speed if (sortby_value == SORTBY_DOWNLOAD) { Collections.sort(torrentsFiltered, new TorrentDownloadSpeedComparator(reverse_order)); } // Sort by upload speed if (sortby_value == SORTBY_UPLOAD) { Collections.sort(torrentsFiltered, new TorrentUploadSpeedComparator(reverse_order)); } // Sort by Added on if (sortby_value == SORTBY_ADDEDON) { if (MainActivity.qb_api == null || Integer.parseInt(MainActivity.qb_api) >= 10) { Collections.sort(torrentsFiltered, new TorrentAddedOnTimestampComparator(reverse_order)); } else { Collections.sort(torrentsFiltered, new TorrentAddedOnComparator(reverse_order)); } } // Sort by Completed on if (sortby_value == SORTBY_COMPLETEDON) { if (MainActivity.qb_api == null || Integer.parseInt(MainActivity.qb_api) >= 10) { Collections.sort(torrentsFiltered, new TorrentCompletedOnTimestampComparator(reverse_order)); } else { Collections.sort(torrentsFiltered, new TorrentCompletedOnComparator(reverse_order)); } } // Get names (delete in background method) MainActivity.names = new String[torrentsFiltered.size()]; MainActivity.lines = new Torrent[torrentsFiltered.size()]; uploadSpeedCount = 0; downloadSpeedCount = 0; uploadCount = 0; downloadCount = 0; try { Torrent torrentToUpdate = null; // Reporting if (CustomLogger.isMainActivityReporting()) { CustomLogger.saveReportMessage("Main", "qBittorrentTask - torrentsFiltered.size: " + torrentsFiltered.size()); } for (int i = 0; i < torrentsFiltered.size(); i++) { Torrent torrent = torrentsFiltered.get(i); MainActivity.names[i] = torrent.getFile(); MainActivity.lines[i] = torrent; if (torrent.getHash() .equals(com.lgallardo.qbittorrentclient.TorrentDetailsFragment.hashToUpdate)) { torrentToUpdate = torrent; } uploadSpeedCount += (int) Common.humanSizeToBytes(torrent.getUploadSpeed()); downloadSpeedCount += (int) Common.humanSizeToBytes(torrent.getDownloadSpeed()); if ("uploading".equals(torrent.getState())) { uploadCount = uploadCount + 1; } if ("downloading".equals(torrent.getState())) { downloadCount = downloadCount + 1; } } // Update torrent list try { myadapter.setNames(names); myadapter.setData(lines); myadapter.notifyDataSetChanged(); } catch (NullPointerException ne) { myadapter = new TorrentListAdapter(MainActivity.this, names, lines); firstFragment.setListAdapter(myadapter); myadapter.setNames(names); myadapter.setData(lines); myadapter.notifyDataSetChanged(); } catch (IllegalStateException le) { Log.e("Debug", "IllegalStateException: " + le.toString()); } // Create the about fragment aboutFragment = new AboutFragment(); // Add the fragment to the 'list_frame' FrameLayout FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); String AltSpeedInfo; if (alternative_speeds) { AltSpeedInfo = Character.toString('\u2713') + " "; } else { AltSpeedInfo = ""; } // Got some results if (torrentsFiltered.size() > 0) { // Set headerInfo TextView uploadSpeedTextView = (TextView) findViewById(R.id.uploadSpeed); TextView downloadSpeedTextView = (TextView) findViewById(R.id.downloadSpeed); headerInfo = (LinearLayout) findViewById(R.id.header); if (header) { headerInfo.setVisibility(View.VISIBLE); } else { headerInfo.setVisibility(View.GONE); } uploadSpeedTextView.setText(AltSpeedInfo + Common.calculateSize("" + uploadSpeedCount) + "/s " + "(" + uploadCount + ")"); downloadSpeedTextView.setText( Character.toString('\u21C5') + " " + Common.calculateSize("" + downloadSpeedCount) + "/s " + "(" + downloadCount + ")"); //Set first and second fragments if (findViewById(R.id.fragment_container) != null) { // Set where is the second container firstFragment.setSecondFragmentContainer(R.id.content_frame); // Set first fragment if (fragmentManager.findFragmentByTag("firstFragment") instanceof HelpFragment) { fragmentTransaction.replace(R.id.list_frame, firstFragment, "firstFragment"); } // Set second fragment if (!(fragmentManager.findFragmentByTag("secondFragment") instanceof AboutFragment)) { com.lgallardo.qbittorrentclient.TorrentDetailsFragment detailsFragment = (com.lgallardo.qbittorrentclient.TorrentDetailsFragment) fragmentManager .findFragmentByTag("secondFragment"); if (torrentToUpdate != null) { // Update torrent details detailsFragment.updateDetails(torrentToUpdate); } else { // Torrent no longer found // Set second fragment with About fragment fragmentTransaction.replace(R.id.content_frame, aboutFragment, "secondFragment"); // Reset back button stack for (int i = 0; i < fragmentManager.getBackStackEntryCount(); ++i) { fragmentManager.popBackStack("secondFragment", FragmentManager.POP_BACK_STACK_INCLUSIVE); } } } else { // Reset back button stack for (int i = 0; i < fragmentManager.getBackStackEntryCount(); ++i) { fragmentManager.popBackStack("secondFragment", FragmentManager.POP_BACK_STACK_INCLUSIVE); } } } else { // Set where is the second container firstFragment.setSecondFragmentContainer(R.id.one_frame); // Set first fragment if (fragmentManager.findFragmentByTag("firstFragment") instanceof AboutFragment) { fragmentTransaction.replace(R.id.one_frame, firstFragment, "firstFragment"); } if (fragmentManager.findFragmentByTag( "firstFragment") instanceof com.lgallardo.qbittorrentclient.TorrentDetailsFragment) { com.lgallardo.qbittorrentclient.TorrentDetailsFragment detailsFragment = (com.lgallardo.qbittorrentclient.TorrentDetailsFragment) fragmentManager .findFragmentByTag("firstFragment"); if (torrentToUpdate != null) { // Update torrent detailsFragment.updateDetails(torrentToUpdate); } else { // Torrent no longer found // Reset back button stack for (int i = 0; i < fragmentManager.getBackStackEntryCount(); ++i) { fragmentManager.popBackStack(); } } } } } else { // No results myadapter.setNames(null); myadapter.setData(null); myadapter.notifyDataSetChanged(); // Hide headerInfo TextView uploadSpeedTextView = (TextView) findViewById(R.id.uploadSpeed); TextView downloadSpeedTextView = (TextView) findViewById(R.id.downloadSpeed); uploadSpeedTextView.setText(AltSpeedInfo); downloadSpeedTextView.setText(""); //Set first and second fragments if (findViewById(R.id.fragment_container) != null) { // Set where is the second container firstFragment.setSecondFragmentContainer(R.id.content_frame); // Set first fragment if (fragmentManager.findFragmentByTag("firstFragment") instanceof HelpFragment) { fragmentTransaction.replace(R.id.list_frame, firstFragment, "firstFragment"); } // Set second fragment if (!(fragmentManager.findFragmentByTag("secondFragment") instanceof AboutFragment)) { fragmentTransaction.replace(R.id.content_frame, aboutFragment, "secondFragment"); // Reset back button stack for (int i = 0; i < fragmentManager.getBackStackEntryCount(); ++i) { fragmentManager.popBackStack("secondFragment", FragmentManager.POP_BACK_STACK_INCLUSIVE); } } } else { // Set where is the second container firstFragment.setSecondFragmentContainer(R.id.one_frame); // Set first fragment if (fragmentManager.findFragmentByTag("firstFragment") instanceof AboutFragment) { fragmentTransaction.replace(R.id.one_frame, firstFragment, "firstFragment"); } // Reset back button stack for (int i = 0; i < fragmentManager.getBackStackEntryCount(); ++i) { fragmentManager.popBackStack(); } } } // Commit fragmentTransaction.commit(); } catch (Exception e) { Log.e("ADAPTER", e.toString()); if (CustomLogger.isMainActivityReporting()) { CustomLogger.saveReportMessage("Main", "[qBittorrentTask - AdapterException]: " + e.toString()); } } } // Send report emailReport(); // Disable refreshSwipeLayout disableRefreshSwipeLayout(); } } // Here is where the action happens private class qBittorrentOptions extends AsyncTask<String, Integer, String> { @Override protected String doInBackground(String... params) { // Get settings getSettings(); // Creating new JSON Parser com.lgallardo.qbittorrentclient.JSONParser jParser = new com.lgallardo.qbittorrentclient.JSONParser( hostname, subfolder, protocol, port, keystore_path, keystore_password, username, password, connection_timeout, data_timeout); jParser.setCookie(cookie); // Get the Json object JSONObject json = null; try { json = jParser.getJSONFromUrl(params[0]); } catch (JSONParserStatusCodeException e) { httpStatusCode = e.getCode(); Log.e("JSONParserStatusCode", e.toString()); } if (json != null) { try { global_max_num_connections = json.getString(TAG_GLOBAL_MAX_NUM_CONNECTIONS); max_num_conn_per_torrent = json.getString(TAG_MAX_NUM_CONN_PER_TORRENT); max_uploads = json.getString(TAG_MAX_UPLOADS); max_num_upslots_per_torrent = json.getString(TAG_MAX_NUM_UPSLOTS_PER_TORRENT); global_upload = json.getString(TAG_GLOBAL_UPLOAD); global_download = json.getString(TAG_GLOBAL_DOWNLOAD); alt_upload = json.getString(TAG_ALT_UPLOAD); alt_download = json.getString(TAG_ALT_DOWNLOAD); torrent_queueing = json.getBoolean(TAG_TORRENT_QUEUEING); max_act_downloads = json.getString(TAG_MAX_ACT_DOWNLOADS); max_act_uploads = json.getString(TAG_MAX_ACT_UPLOADS); max_act_torrents = json.getString(TAG_MAX_ACT_TORRENTS); schedule_alternative_rate_limits = json.getBoolean(TAG_SCHEDULER_ENABLED); alt_from_hour = json.getString(TAG_SCHEDULE_FROM_HOUR); alt_from_min = json.getString(TAG_SCHEDULE_FROM_MIN); alt_to_hour = json.getString(TAG_SCHEDULE_TO_HOUR); alt_to_min = json.getString(TAG_SCHEDULE_TO_MIN); scheduler_days = json.getString(TAG_SCHEDULER_DAYS); max_ratio_enabled = json.getBoolean(TAG_MAX_RATIO_ENABLED); max_ratio = json.getString(TAG_MAX_RATIO); max_ratio_act = json.getString(TAG_MAX_RATIO_ACT); // Log.d("Debug", "2) max_ratio: " + max_ratio); // Save options locally sharedPrefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); Editor editor = sharedPrefs.edit(); // Save key-values editor.putString("global_max_num_connections", global_max_num_connections); editor.putString("max_num_conn_per_torrent", max_num_conn_per_torrent); editor.putString("max_uploads", max_uploads); editor.putString("max_num_upslots_per_torrent", max_num_upslots_per_torrent); editor.putString("global_upload", global_upload); editor.putString("global_download", global_download); editor.putString("alt_upload", alt_upload); editor.putString("alt_download", alt_download); editor.putBoolean("torrent_queueing", torrent_queueing); editor.putString("max_act_downloads", max_act_downloads); editor.putString("max_act_uploads", max_act_uploads); editor.putString("max_act_torrents", max_act_torrents); editor.putBoolean("schedule_alternative_rate_limits", schedule_alternative_rate_limits); editor.putString("alt_from", alt_from_hour + ":" + alt_from_min); editor.putString("alt_to", alt_to_hour + ":" + alt_to_min); editor.putString("scheduler_days", scheduler_days); editor.putBoolean("max_ratio_enabled", max_ratio_enabled); editor.putString("max_ratio", max_ratio); editor.putString("max_ratio_act", max_ratio_act); // Commit changes editor.commit(); } catch (Exception e) { Log.e("MAIN:", e.toString()); return null; } } // Return getSettings or setSettings return params[1]; } @Override protected void onPostExecute(String result) { if (result == null) { toastText(R.string.connection_error); // Handle HTTP status code if (httpStatusCode == 1) { toastText(R.string.error1); httpStatusCode = 0; } if (httpStatusCode == 2) { toastText(R.string.error2); httpStatusCode = 0; } if (httpStatusCode == 401) { toastText(R.string.error401); httpStatusCode = 0; } if (httpStatusCode == 403 || httpStatusCode == 404) { toastText(R.string.error403); httpStatusCode = 0; disableRefreshSwipeLayout(); if (qb_version.equals("3.2.x")) { // Get new Cookie cookie = null; } } } else { // Set options with the preference UI if (result.equals("setOptions")) { // Open options activity openOptions(); } // Get options only if (result.equals("getOptions")) { // Do nothing } } } } // Drawer classes private class DrawerItemClickListener implements ListView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { selectItem(position); } } }