MainActivity.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. package com.chinaappsremover.ui;
  2. import android.content.ActivityNotFoundException;
  3. import android.content.BroadcastReceiver;
  4. import android.content.Context;
  5. import android.content.Intent;
  6. import android.content.IntentSender;
  7. import android.content.pm.ApplicationInfo;
  8. import android.content.pm.PackageInfo;
  9. import android.content.res.Resources;
  10. import android.net.Uri;
  11. import android.os.AsyncTask;
  12. import android.os.Bundle;
  13. import android.os.Handler;
  14. import android.text.Html;
  15. import android.util.Log;
  16. import android.view.Menu;
  17. import android.view.MenuItem;
  18. import android.view.View;
  19. import android.widget.Button;
  20. import android.widget.ImageView;
  21. import android.widget.ProgressBar;
  22. import android.widget.RelativeLayout;
  23. import android.widget.TextView;
  24. import androidx.annotation.Nullable;
  25. import androidx.appcompat.app.ActionBar;
  26. import androidx.appcompat.app.AppCompatActivity;
  27. import androidx.recyclerview.widget.DefaultItemAnimator;
  28. import androidx.recyclerview.widget.LinearLayoutManager;
  29. import androidx.recyclerview.widget.RecyclerView;
  30. import com.chinaappsremover.AppController;
  31. import com.chinaappsremover.R;
  32. import com.chinaappsremover.adapter.ItemlistAdapter;
  33. import com.chinaappsremover.dbhandler.DataBaseHelper;
  34. import com.chinaappsremover.listener.OnItemClickListener;
  35. import com.chinaappsremover.network.ChinaAppsDataDownloader;
  36. import com.chinaappsremover.network.ChinaAppsDataParser;
  37. import com.chinaappsremover.utils.NetworkUtils;
  38. import com.chinaappsremover.utils.Preference;
  39. import com.chinaappsremover.wrapper.AppInfo;
  40. import com.google.android.material.snackbar.Snackbar;
  41. import com.google.android.play.core.appupdate.AppUpdateInfo;
  42. import com.google.android.play.core.appupdate.AppUpdateManager;
  43. import com.google.android.play.core.appupdate.AppUpdateManagerFactory;
  44. import com.google.android.play.core.install.InstallState;
  45. import com.google.android.play.core.install.InstallStateUpdatedListener;
  46. import com.google.android.play.core.install.model.AppUpdateType;
  47. import com.google.android.play.core.install.model.InstallStatus;
  48. import com.google.android.play.core.install.model.UpdateAvailability;
  49. import com.google.android.play.core.tasks.OnSuccessListener;
  50. import java.io.File;
  51. import java.io.IOException;
  52. import java.io.InputStream;
  53. import java.util.ArrayList;
  54. import java.util.Collections;
  55. import java.util.Comparator;
  56. import java.util.List;
  57. import okhttp3.Response;
  58. public class MainActivity extends AppCompatActivity implements OnItemClickListener {
  59. private static final int RC_APP_UPDATE = 201;
  60. private TextView app_found_count;
  61. private ImageView doneIcon;
  62. private ImageView dragonIcon;
  63. private RelativeLayout listLayout;
  64. private RelativeLayout noappsfoundLayout;
  65. private ProgressBar progressBar;
  66. private RecyclerView recycler_view;
  67. private Button rescan_now;
  68. private Button scan_now;
  69. private RelativeLayout scan_ui;
  70. private ImageView shareIcon;
  71. private List<AppInfo> appInfos = new ArrayList<>();
  72. InstallStateUpdatedListener installStateUpdatedListener = new InstallStateUpdatedListener() {
  73. public void onStateUpdate(InstallState installState) {
  74. try {
  75. if (installState.installStatus() == InstallStatus.DOWNLOADED) {
  76. popupSnackbarForCompleteUpdate();
  77. } else if (installState.installStatus() != InstallStatus.INSTALLED) {
  78. Log.i("MainActivity", "InstallStateUpdatedListener: state: " + installState.installStatus());
  79. } else if (mAppUpdateManager != null) {
  80. mAppUpdateManager.unregisterListener(installStateUpdatedListener);
  81. }
  82. } catch (Exception e) {
  83. e.printStackTrace();
  84. }
  85. }
  86. };
  87. private ItemlistAdapter itemlistAdapter;
  88. AppUpdateManager mAppUpdateManager;
  89. private boolean isDeleteClick;
  90. protected void onCreate(Bundle bundle) {
  91. super.onCreate(bundle);
  92. setContentView(R.layout.activity_main);
  93. ActionBar supportActionBar = getSupportActionBar();
  94. if (supportActionBar != null) {
  95. supportActionBar.setHomeAsUpIndicator(R.mipmap.ic_launcher);
  96. }
  97. progressBar = findViewById(R.id.progressBar);
  98. dragonIcon = findViewById(R.id.dragonIcon);
  99. doneIcon = findViewById(R.id.doneIcon);
  100. shareIcon = findViewById(R.id.shareIcon);
  101. scan_now = findViewById(R.id.scan_now);
  102. recycler_view = findViewById(R.id.recycler_view);
  103. listLayout = findViewById(R.id.listLayout);
  104. scan_ui = findViewById(R.id.scan_ui);
  105. noappsfoundLayout = findViewById(R.id.noappsfoundLayout);
  106. app_found_count = findViewById(R.id.app_found_count);
  107. rescan_now = findViewById(R.id.rescan_now);
  108. itemlistAdapter = new ItemlistAdapter(this, appInfos, this);
  109. recycler_view.setLayoutManager(new LinearLayoutManager(this));
  110. recycler_view.setItemAnimator(new DefaultItemAnimator());
  111. recycler_view.setAdapter(itemlistAdapter);
  112. ((TextView) findViewById(R.id.scan_now_txt)).setText(Html.fromHtml(getResources().getString(R.string.clickscantext)));
  113. scan_now.setOnClickListener(new View.OnClickListener() {
  114. public void onClick(View view) {
  115. getApps();
  116. }
  117. });
  118. rescan_now.setOnClickListener(new View.OnClickListener() {
  119. public void onClick(View view) {
  120. getApps();
  121. }
  122. });
  123. checkAppUpdate();
  124. shareIcon.setOnClickListener(new View.OnClickListener() {
  125. public void onClick(View view) {
  126. shareApp();
  127. }
  128. });
  129. }
  130. private void checkAppUpdate() {
  131. try {
  132. mAppUpdateManager = AppUpdateManagerFactory.create(this);
  133. mAppUpdateManager.registerListener(installStateUpdatedListener);
  134. mAppUpdateManager.getAppUpdateInfo().addOnSuccessListener(new OnSuccessListener<AppUpdateInfo>() {
  135. public void onSuccess(AppUpdateInfo appUpdateInfo) {
  136. if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
  137. try {
  138. mAppUpdateManager.startUpdateFlowForResult(appUpdateInfo, AppUpdateType.FLEXIBLE, MainActivity.this, RC_APP_UPDATE);
  139. } catch (IntentSender.SendIntentException e) {
  140. e.printStackTrace();
  141. }
  142. } else if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
  143. popupSnackbarForCompleteUpdate();
  144. } else {
  145. Log.e("MainActivity", "checkForAppUpdateAvailability: something else");
  146. }
  147. }
  148. });
  149. } catch (Exception e) {
  150. e.printStackTrace();
  151. }
  152. }
  153. @Override
  154. protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
  155. super.onActivityResult(requestCode, resultCode, data);
  156. if (requestCode == RC_APP_UPDATE && resultCode != RESULT_OK
  157. ) {
  158. Log.e("onActivityResult", "onActivityResult: app download failed");
  159. }
  160. }
  161. private void popupSnackbarForCompleteUpdate() {
  162. try {
  163. Snackbar make = Snackbar.make(findViewById(R.id.scan_ui), "An update has just been downloaded.", Snackbar.LENGTH_INDEFINITE);
  164. make.setAction("RESTART", new View.OnClickListener() {
  165. public void onClick(View view) {
  166. if (mAppUpdateManager != null) {
  167. mAppUpdateManager.completeUpdate();
  168. }
  169. }
  170. });
  171. make.setActionTextColor(getResources().getColor(R.color.green));
  172. make.show();
  173. } catch (Resources.NotFoundException e) {
  174. e.printStackTrace();
  175. }
  176. }
  177. private void getApps() {
  178. new GetAppsAsync().execute();
  179. }
  180. protected void onResume() {
  181. super.onResume();
  182. if (isDeleteClick) {
  183. new Handler().postDelayed(new Runnable() {
  184. public void run() {
  185. getApps();
  186. }
  187. }, 1500);
  188. }
  189. isDeleteClick = false;
  190. }
  191. public void onItemClick(int i) {
  192. isDeleteClick = true;
  193. }
  194. class AppUninstalledreceiver extends BroadcastReceiver {
  195. AppUninstalledreceiver() {
  196. }
  197. public void onReceive(Context context, Intent intent) {
  198. getApps();
  199. }
  200. }
  201. enum NetworkRefreshState {
  202. ONGOING,
  203. COMPLETED,
  204. FAILED
  205. }
  206. class GetAppsAsync extends AsyncTask<Void, NetworkRefreshState, List<AppInfo>> {
  207. private Snackbar snackbar;
  208. GetAppsAsync() {
  209. snackbar = Snackbar.make(findViewById(R.id.scan_ui), "Refreshing database from the network...", Snackbar.LENGTH_INDEFINITE);
  210. }
  211. protected void onPreExecute() {
  212. super.onPreExecute();
  213. progressBar.setVisibility(View.VISIBLE);
  214. scan_ui.setVisibility(View.GONE);
  215. }
  216. protected List<AppInfo> doInBackground(Void... voidArr) {
  217. DataBaseHelper dbHelper = AppController.getDbHelper();
  218. if (NetworkUtils.hasNetworkConnection() && Preference.shouldRefreshData()) {
  219. Log.d("MainActivity", "Refreshing database from the network...");
  220. publishProgress(NetworkRefreshState.ONGOING);
  221. ChinaAppsDataDownloader dataDownloader = ChinaAppsDataDownloader.getInstance(getApplicationContext());
  222. try {
  223. Thread.sleep(5000L);
  224. } catch (InterruptedException e) {
  225. e.printStackTrace();
  226. }
  227. try {
  228. Response response = dataDownloader.fetch(false);
  229. List<AppInfo> appInfoList = ChinaAppsDataParser.parse(response);
  230. if (appInfoList != null && dbHelper.refreshAppInfos(appInfoList)) {
  231. Log.d("MainActivity", "Refreshed database from the network.");
  232. Preference.updateLastSyncMills();
  233. Preference.setDbInitialized();
  234. publishProgress(NetworkRefreshState.COMPLETED);
  235. } else {
  236. publishProgress(NetworkRefreshState.FAILED);
  237. }
  238. } catch (IOException e) {
  239. e.printStackTrace();
  240. }
  241. } else {
  242. if (Preference.isDbInitialized()) {
  243. Log.d("MainActivity", "DB not initialized, initializing database from local json...");
  244. try {
  245. InputStream stream = getApplicationContext().getAssets().open("china_apps.json");
  246. List<AppInfo> appInfoList = ChinaAppsDataParser.parse(stream);
  247. if (appInfoList != null && dbHelper.refreshAppInfos(appInfoList)) {
  248. Preference.setDbInitialized();
  249. Log.d("MainActivity", "Initialized database from local json.");
  250. }
  251. } catch (Exception e) {
  252. e.printStackTrace();
  253. }
  254. }
  255. }
  256. return dbHelper.isExist(getInstalledApps(), appInfos);
  257. }
  258. @Override
  259. protected void onProgressUpdate(NetworkRefreshState... values) {
  260. super.onProgressUpdate(values);
  261. if (values != null && values.length > 0) {
  262. NetworkRefreshState networkRefreshState = values[0];
  263. if (networkRefreshState == NetworkRefreshState.ONGOING) {
  264. snackbar.show();
  265. } else {
  266. snackbar.dismiss();
  267. if (networkRefreshState == NetworkRefreshState.COMPLETED) {
  268. Snackbar.make(findViewById(R.id.scan_ui), "Database refreshed successfully.", Snackbar.LENGTH_SHORT).show();
  269. }else {
  270. Snackbar.make(findViewById(R.id.scan_ui), "Aw, Snap! Something went wrong while refreshing.", Snackbar.LENGTH_SHORT).show();
  271. }
  272. }
  273. }
  274. }
  275. protected void onPostExecute(List<AppInfo> list) {
  276. super.onPostExecute(list);
  277. progressBar.setVisibility(View.GONE);
  278. scan_ui.setVisibility(View.GONE);
  279. if (list.size() > 0) {
  280. listLayout.setVisibility(View.VISIBLE);
  281. noappsfoundLayout.setVisibility(View.GONE);
  282. app_found_count.setText(Html.fromHtml(getResources().getString(R.string.app_found_count, list.size())));
  283. } else {
  284. listLayout.setVisibility(View.GONE);
  285. noappsfoundLayout.setVisibility(View.VISIBLE);
  286. }
  287. dragonIcon.setVisibility(View.GONE);
  288. doneIcon.setVisibility(View.VISIBLE);
  289. itemlistAdapter.notifyDataSetChanged();
  290. if (list.size() == 0) {
  291. Collections.sort(appInfos, new Comparator<AppInfo>() {
  292. public int compare(AppInfo appInfo, AppInfo appInfo2) {
  293. return appInfo.appName.compareToIgnoreCase(appInfo2.appName);
  294. }
  295. });
  296. }
  297. }
  298. }
  299. public boolean onCreateOptionsMenu(Menu menu) {
  300. getMenuInflater().inflate(R.menu.main, menu);
  301. return super.onCreateOptionsMenu(menu);
  302. }
  303. public boolean onOptionsItemSelected(MenuItem menuItem) {
  304. int itemId = menuItem.getItemId();
  305. if (itemId == R.id.contact_us) {
  306. openUrl(getResources().getString(R.string.contact_us_url));
  307. return true;
  308. } else if (itemId == R.id.privacy_policy) {
  309. openUrl(getResources().getString(R.string.privacy_policy_url));
  310. return true;
  311. } else if (itemId != R.id.rate_us) {
  312. return super.onOptionsItemSelected(menuItem);
  313. } else {
  314. rateus();
  315. return true;
  316. }
  317. }
  318. private void openUrl(String str) {
  319. startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(str)));
  320. }
  321. private void rateus() {
  322. Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + getPackageName()));
  323. try {
  324. startActivity(intent);
  325. } catch (ActivityNotFoundException unused) {
  326. startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=" + getPackageName())));
  327. }
  328. }
  329. public void shareApp() {
  330. try {
  331. Intent intent = new Intent("android.intent.action.SEND");
  332. intent.setType("text/plain");
  333. intent.putExtra("android.intent.extra.SUBJECT", getResources().getString(R.string.app_name));
  334. intent.putExtra("android.intent.extra.TEXT", "\nHey, I am using Remove China Apps to get rid of Chinese apps. If you want the same try using the app by clicking\n\n" + "https://play.google.com/store/apps/details?id=" + getPackageName() + "\n\n");
  335. startActivity(Intent.createChooser(intent, "choose one"));
  336. } catch (Exception e) {
  337. e.printStackTrace();
  338. }
  339. }
  340. private boolean isSystemPackage(PackageInfo packageInfo) {
  341. return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
  342. }
  343. public List<AppInfo> getInstalledApps() {
  344. ArrayList<AppInfo> arrayList = new ArrayList<>();
  345. List<PackageInfo> installedPackages = getPackageManager().getInstalledPackages(0);
  346. for (int i = 0; i < installedPackages.size(); i++) {
  347. PackageInfo packageInfo = installedPackages.get(i);
  348. if (!isSystemPackage(packageInfo)) {
  349. AppInfo appInfo = new AppInfo();
  350. appInfo.appName = packageInfo.applicationInfo.loadLabel(getPackageManager()).toString();
  351. appInfo.packageName = packageInfo.packageName;
  352. appInfo.versionName = packageInfo.versionName;
  353. appInfo.versionCode = packageInfo.versionCode;
  354. appInfo.icon = packageInfo.applicationInfo.loadIcon(getPackageManager());
  355. appInfo.size = (new File(packageInfo.applicationInfo.publicSourceDir).length() / 1024 * 1024) + " MB";
  356. arrayList.add(appInfo);
  357. }
  358. }
  359. return arrayList;
  360. }
  361. }