MainActivity.java 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. package com.knacki.mimou.activity;
  2. import android.Manifest;
  3. import android.content.Context;
  4. import android.content.DialogInterface;
  5. import android.content.Intent;
  6. import android.content.pm.PackageManager;
  7. import android.net.Uri;
  8. import android.os.Build;
  9. import android.os.Bundle;
  10. import android.os.Handler;
  11. import android.os.Looper;
  12. import android.support.annotation.NonNull;
  13. import android.support.v4.app.ActivityCompat;
  14. import android.support.v4.view.MenuCompat;
  15. import android.support.v7.app.AlertDialog;
  16. import android.support.v7.app.AppCompatActivity;
  17. import android.view.Menu;
  18. import android.view.MenuItem;
  19. import android.webkit.WebChromeClient;
  20. import android.webkit.WebView;
  21. import android.webkit.WebViewClient;
  22. import com.knacki.mimou.BuildConfig;
  23. import com.knacki.mimou.bridge.JavascriptFunction;
  24. import com.knacki.mimou.preference.CredentialHolder;
  25. import com.knacki.mimou.bridge.JsInterface;
  26. import com.knacki.mimou.R;
  27. import com.knacki.mimou.preference.UserSettings;
  28. import java.util.List;
  29. import java.util.logging.Logger;
  30. public class MainActivity extends AppCompatActivity {
  31. public final static int SMS_PERMISSION_CALLBACK = 42;
  32. protected WebView web;
  33. protected JsInterface interfaceMimouDroid;
  34. protected MainActivityMenu menu;
  35. protected String currentChannel = null;
  36. public static boolean needReload = true;
  37. private static Logger log = Logger.getLogger(MainActivity.class.getName());
  38. private JsInterface.TypedCallback<Boolean> currentCallback = null;
  39. @Override
  40. protected void onCreate(Bundle savedInstanceState) {
  41. super.onCreate(savedInstanceState);
  42. setContentView(R.layout.activity_main);
  43. interfaceMimouDroid = new JsInterface();
  44. web = (WebView) findViewById(R.id.webview);
  45. web.setWebChromeClient(new WebChromeClient());
  46. web.setWebViewClient(new WebViewClient() {
  47. @Override
  48. public boolean shouldOverrideUrlLoading(WebView view, String url) {
  49. Uri uri = Uri.parse(url);
  50. log.severe("Loading url " +url);
  51. if (uri.getHost().equals(getString(R.string.mimouHost))) {
  52. List<String> pathSegments = uri.getPathSegments();
  53. if (pathSegments.size() > 0) {
  54. if (pathSegments.get(0).equals("login") && !url.contains("?phoneAccess=")) {
  55. CredentialHolder.reset(MainActivity.this);
  56. showLogin();
  57. return true;
  58. }
  59. }
  60. return super.shouldOverrideUrlLoading(view, url);
  61. }
  62. startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
  63. return true;
  64. }
  65. });
  66. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  67. web.setWebContentsDebuggingEnabled(BuildConfig.DEBUG);
  68. }
  69. web.getSettings().setJavaScriptEnabled(true);
  70. web.addJavascriptInterface(interfaceMimouDroid, "__native");
  71. needReload = true;
  72. Uri intentUri = getIntent().getData();
  73. if (intentUri != null) {
  74. String securityToken = intentUri.getQueryParameter("token");
  75. if (securityToken != null) {
  76. CredentialHolder.setSecurityToken(this, securityToken);
  77. }
  78. }
  79. reload();
  80. }
  81. @Override
  82. public boolean onCreateOptionsMenu(Menu m) {
  83. getMenuInflater().inflate(R.menu.title_opt, m);
  84. menu = new MainActivityMenu(m);
  85. menu.setFavoriteEnabled(false);
  86. return true;
  87. }
  88. public void uiThread(Runnable e) {
  89. new Handler(Looper.getMainLooper()).post(e);
  90. }
  91. public void reload() {
  92. if (needReload && web != null) {
  93. if (CredentialHolder.hasCredential(this)) {
  94. final String url = getString(R.string.mimouUrl) + (CredentialHolder.isLocal(this) ? getString(R.string.localUrl) : (getString(R.string.loginUrl) + "/android?phoneAccess=" +CredentialHolder.getToken(this)));
  95. log.fine("Loading URL: " +url);
  96. web.loadUrl(url);
  97. } else {
  98. showLogin();
  99. }
  100. }
  101. needReload = false;
  102. }
  103. public void showLogin() {
  104. startActivity(new Intent(MainActivity.this, LoginActivity.class));
  105. }
  106. @Override
  107. protected void onResume() {
  108. super.onResume();
  109. if (!CredentialHolder.hasCredential(this))
  110. showLogin();
  111. else
  112. reload();
  113. interfaceMimouDroid.setActivity(this);
  114. }
  115. @Override
  116. protected void onDestroy() {
  117. super.onDestroy();
  118. if (web != null) {
  119. web.removeAllViews();
  120. web.clearHistory();
  121. web.clearCache(true);
  122. web.destroyDrawingCache();
  123. web.pauseTimers();
  124. web.destroy();
  125. web = null;
  126. }
  127. }
  128. private void runJavascript(final String js) {
  129. uiThread(new Runnable() {
  130. @Override
  131. public void run() {
  132. if (web != null)
  133. web.loadUrl("javascript:" +js);
  134. }
  135. });
  136. }
  137. public void runJavascript(JavascriptFunction fnc) {
  138. runJavascript(fnc.toString());
  139. }
  140. @Override
  141. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
  142. boolean allGranted = true;
  143. for (int grantResult: grantResults) {
  144. if (grantResult != PackageManager.PERMISSION_GRANTED) {
  145. allGranted = false;
  146. break;
  147. }
  148. }
  149. if (currentCallback != null) {
  150. currentCallback.onResult(allGranted);
  151. currentCallback = null;
  152. }
  153. }
  154. public void setCurrentChannel(String channelId) {
  155. currentChannel = channelId;
  156. }
  157. public void setTitle(final CharSequence title, final Boolean isFavorite) {
  158. uiThread(new Runnable() {
  159. @Override
  160. public void run() {
  161. setTitle(title);
  162. if (isFavorite == null) {
  163. menu.setFavoriteEnabled(false);
  164. } else {
  165. menu.setFavoriteEnabled(true);
  166. menu.setFavorite(isFavorite);
  167. }
  168. }
  169. });
  170. }
  171. private void promptAndroidPermission() {
  172. ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.READ_SMS, Manifest.permission.SEND_SMS}, SMS_PERMISSION_CALLBACK);
  173. }
  174. private void promptSmsPermission(final JsInterface.TypedCallback<Boolean> callback) {
  175. new AlertDialog.Builder(this)
  176. .setMessage(getString(R.string.useSmsPermission))
  177. .setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
  178. @Override
  179. public void onClick(DialogInterface dialogInterface, int i) {
  180. CredentialHolder.setSMSPermission(MainActivity.this, false);
  181. currentCallback = callback;
  182. promptAndroidPermission();
  183. }
  184. })
  185. .setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() {
  186. @Override
  187. public void onClick(DialogInterface dialogInterface, int i) {
  188. CredentialHolder.setSMSPermission(MainActivity.this, false);
  189. callback.onResult(false);
  190. }
  191. })
  192. .setCancelable(false)
  193. .show();
  194. }
  195. public void requestSmsPermission(JsInterface.TypedCallback<Boolean> callback) {
  196. Boolean userPermission = CredentialHolder.hasSMSPermission(this);
  197. if (userPermission == null) {
  198. promptSmsPermission(callback);
  199. } else if (userPermission == false) {
  200. callback.onResult(false);
  201. } else {
  202. currentCallback = callback;
  203. promptAndroidPermission();
  204. }
  205. }
  206. @Override
  207. public void onBackPressed() {
  208. if (UserSettings.backShowMenu(this))
  209. runJavascript(new JavascriptFunction("displayMenu"));
  210. else
  211. moveTaskToBack(true);
  212. }
  213. class MainActivityMenu {
  214. protected MenuItem favoriteButton;
  215. protected MenuItem menuButton;
  216. protected boolean favoriteEnabled;
  217. protected boolean isFavorite;
  218. MainActivityMenu(Menu menu) {
  219. favoriteButton = menu.getItem(0);
  220. menuButton = menu.getItem(1);
  221. favoriteButton.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
  222. @Override
  223. public boolean onMenuItemClick(MenuItem menuItem) {
  224. if (favoriteEnabled && currentChannel != null) {
  225. runJavascript(new JavascriptFunction("setChannelFavorite").addArgument(currentChannel).addArgument(!isFavorite));
  226. }
  227. return true;
  228. }
  229. });
  230. menuButton.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
  231. @Override
  232. public boolean onMenuItemClick(MenuItem menuItem) {
  233. runJavascript(new JavascriptFunction("toggleMenu"));
  234. return true;
  235. }
  236. });
  237. }
  238. public void setFavoriteEnabled(boolean enabled) {
  239. favoriteButton.setVisible(enabled);
  240. favoriteEnabled = enabled;
  241. }
  242. public void setFavorite(boolean isFav) {
  243. isFavorite = isFav;
  244. favoriteButton.setTitle(isFav ? "STARRED" : "NOT STARRED");
  245. //favoriteButton.setIcon(MainActivity.this.getDrawable(R.drawable.favorite));
  246. }
  247. }
  248. }