Advertisement
am_dot_com

DDM 20210112

Jan 12th, 2021 (edited)
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 36.43 KB | None | 0 0
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <menu xmlns:android="http://schemas.android.com/apk/res/android">
  3.  
  4. <item
  5. android:id="@+id/idMenuItemExampleLoadImageFromUrl"
  6. android:title="@string/strMenuItemExampleLoadImageFromUrl"></item>
  7.  
  8. </menu>
  9.  
  10. //attaches the menu to the Activity
  11. @Override
  12. public boolean onCreateOptionsMenu(Menu pMenu) {
  13. MenuInflater minf = getMenuInflater();
  14. minf.inflate(
  15. R.menu.my_menu,
  16. pMenu
  17. );
  18. return super.onCreateOptionsMenu(pMenu);
  19. }//onCreateOptionsMenu
  20.  
  21. //code the behavior of each menu item
  22. @Override
  23. public boolean onOptionsItemSelected(
  24. @NonNull MenuItem pItem
  25. )
  26. {
  27. switch(pItem.getItemId()){
  28. case R.id.idMenuItemExampleLoadImageFromUrl:
  29.  
  30. break;
  31. }//switch
  32.  
  33. return super.onOptionsItemSelected(pItem);
  34. }//onOptionsItemSelected
  35.  
  36. ////////
  37.  
  38. package com.joythis.android.textcapturer;
  39.  
  40. import android.graphics.Bitmap;
  41. import android.graphics.BitmapFactory;
  42. import android.util.Log;
  43.  
  44. import java.io.BufferedReader;
  45. import java.io.InputStream;
  46. import java.io.InputStreamReader;
  47. import java.net.HttpURLConnection;
  48. import java.net.URL;
  49.  
  50. import javax.net.ssl.HttpsURLConnection;
  51.  
  52. /**
  53. * Created by Artur Marques on 2018.
  54. */
  55.  
  56. public class AmIoHttp {
  57.  
  58. public static String io_https_ReadAll(
  59. String pUrl
  60. ){
  61. String ret="";
  62. HttpURLConnection urlConnection = null;
  63. try {
  64. URL url = new URL(pUrl);
  65.  
  66. urlConnection = (HttpsURLConnection) url.openConnection();
  67. InputStream in = urlConnection.getInputStream();
  68. InputStreamReader isr = new InputStreamReader(in);
  69. BufferedReader br = new BufferedReader(isr);
  70.  
  71. String strLine = "";
  72. while ((strLine = br.readLine())!=null){
  73. ret+=strLine;
  74. }
  75.  
  76. br.close();
  77. isr.close();
  78. in.close();
  79. } catch (Exception e) {
  80. e.printStackTrace();
  81. } finally //The finally block always executes when the try block exits
  82. {
  83. if (urlConnection != null) {
  84. urlConnection.disconnect();
  85. }//if
  86. }//finally
  87. return ret;
  88. }//io_https_ReadAll
  89.  
  90. public static String io_http_ReadAll(
  91. String pUrl
  92. ){
  93. String ret="";
  94. HttpURLConnection urlConnection = null;
  95. try {
  96. URL url = new URL(pUrl);
  97.  
  98. urlConnection = (HttpURLConnection) url.openConnection();
  99. InputStream in = urlConnection.getInputStream();
  100. InputStreamReader isr = new InputStreamReader(in);
  101. BufferedReader br = new BufferedReader(isr);
  102.  
  103. String strLine = "";
  104. while ((strLine = br.readLine())!=null){
  105. ret+=strLine;
  106. }
  107.  
  108. br.close();
  109. isr.close();
  110. in.close();
  111. } catch (Exception e) {
  112. e.printStackTrace();
  113. } finally //The finally block always executes when the try block exits
  114. {
  115. if (urlConnection != null) {
  116. urlConnection.disconnect();
  117. }//if
  118. }//finally
  119. return ret;
  120. }//io_http_ReadAll
  121.  
  122.  
  123. public final static String TAG = "@AmIoHttp";
  124. public static Bitmap readBitmapFromUrl(
  125. String pUrl
  126. ){
  127. Bitmap ret = null;
  128.  
  129. try{
  130. URL url = new URL(pUrl);
  131. InputStream is = url.openStream();
  132. ret = BitmapFactory.decodeStream(is);
  133. is.close();
  134. }
  135. catch (Exception e){
  136. Log.e(
  137. TAG,
  138. e.getMessage()
  139. );
  140. }
  141.  
  142. return ret;
  143. }//readBitmapFromUrl
  144. }//AmIoHttp
  145.  
  146. //
  147.  
  148. package com.joythis.android.textcapturer;
  149.  
  150. import android.app.Activity;
  151. import android.content.Intent;
  152. import android.content.pm.PackageManager;
  153. import android.util.Log;
  154. import android.view.ViewGroup;
  155. import android.widget.ArrayAdapter;
  156. import android.widget.Button;
  157. import android.widget.EditText;
  158. import android.widget.LinearLayout;
  159. import android.widget.Spinner;
  160. import android.widget.Toast;
  161.  
  162. import androidx.core.content.ContextCompat;
  163.  
  164. import java.io.BufferedReader;
  165. import java.io.FileInputStream;
  166. import java.io.FileOutputStream;
  167. import java.io.InputStream;
  168. import java.io.InputStreamReader;
  169. import java.io.OutputStreamWriter;
  170. import java.net.HttpURLConnection;
  171. import java.net.URL;
  172. import java.nio.charset.StandardCharsets;
  173. import java.util.ArrayList;
  174. import java.util.Calendar;
  175. import java.util.HashMap;
  176. import java.util.Map;
  177. import java.util.Random;
  178.  
  179. import javax.net.ssl.HttpsURLConnection;
  180.  
  181. public class AmUtil {
  182. public final static String E_EMPTY_STRING =
  183. "cannot parse an empty string";
  184.  
  185. public final static String E_CANNOT_PARSE_INT_FROM_STRING =
  186. "cannot parse int from existing string";
  187.  
  188. public final static String E_NO_EDITTEXT =
  189. "null EditText is not parseable";
  190.  
  191. public final static String TAG_AM_UTIL = "@AmUtil";
  192.  
  193. Activity mActivity;
  194.  
  195. public AmUtil(Activity pA){
  196. this.mActivity = pA;
  197. }//AmUtil
  198.  
  199. public void fb(
  200. String pStrMsg
  201. ){
  202. Toast t = Toast.makeText(
  203. this.mActivity,
  204. pStrMsg,
  205. Toast.LENGTH_LONG
  206. );
  207. t.show();
  208. }//fb
  209.  
  210. /*
  211. public void phoneTo(
  212. String pStrPhoneNumber
  213. ){
  214. try {
  215. Uri uriForPhoneNumber = Uri.parse("tel:" + pStrPhoneNumber);
  216.  
  217. Intent intentForMakingThePhoneCall =
  218. new Intent(
  219. Intent.ACTION_CALL
  220. );
  221.  
  222. intentForMakingThePhoneCall.setData(
  223. uriForPhoneNumber
  224. );
  225.  
  226. boolean bUserAuthorizedTheAppToMakePhoneCalls =
  227. ContextCompat.checkSelfPermission(
  228. mActivity,
  229. Manifest.permission.CALL_PHONE
  230. ) == PackageManager.PERMISSION_GRANTED;
  231.  
  232. if (bUserAuthorizedTheAppToMakePhoneCalls) {
  233. this.mActivity.startActivity(
  234. intentForMakingThePhoneCall
  235. );
  236. }
  237. else{
  238. boolean bUserAcceptsExplanationsOnWhyThePermissionIsImportant =
  239. mActivity.shouldShowRequestPermissionRationale(
  240. Manifest.permission.CALL_PHONE
  241. );
  242. if (bUserAcceptsExplanationsOnWhyThePermissionIsImportant){
  243. fb("Without this permission, the app can NOT make phone calls.");
  244. }
  245. }
  246. }//try
  247. catch(Exception e){
  248. Log.e(
  249. getClass().getName(),
  250. e.toString()
  251. );
  252. }//catch
  253. }//phoneTo
  254.  
  255. */
  256.  
  257. public Map<Integer, ArrayList<String>>
  258. identifyPermissionsGrantedAndDenied(
  259. String[] paNecessaryPermissions
  260. )
  261. {
  262. Map<Integer, ArrayList<String>> retMap = new HashMap<>();
  263. ArrayList<String> alGranted = new ArrayList<>();
  264. ArrayList<String> alDenied = new ArrayList<>();
  265.  
  266. for (String permission : paNecessaryPermissions){
  267. boolean bGranted =
  268. ContextCompat.checkSelfPermission(
  269. mActivity,
  270. permission
  271. ) == PackageManager.PERMISSION_GRANTED;
  272.  
  273. boolean bDenied =
  274. ContextCompat.checkSelfPermission(
  275. mActivity,
  276. permission
  277. ) == PackageManager.PERMISSION_DENIED;
  278.  
  279. if (bGranted) alGranted.add(permission);
  280. if (bDenied) alDenied.add(permission);
  281. }//for
  282.  
  283. retMap.put(/* Integer 0 */ PackageManager.PERMISSION_GRANTED, alGranted);
  284. retMap.put(/* Integer -1 */ PackageManager.PERMISSION_DENIED, alDenied);
  285.  
  286. return retMap;
  287. }//identifyPermissionsGrantedAndDenied
  288.  
  289. public void requestNecessaryPermissionsNotYetGranted(
  290. String[] paNecessaryPermissions,
  291. int piCallBackCodeForWhenTheUserResponds
  292. ){
  293. /*
  294. do not request permissions already granted
  295. */
  296. Map<Integer, ArrayList<String>> map =
  297. this.identifyPermissionsGrantedAndDenied
  298. (paNecessaryPermissions);
  299.  
  300. ArrayList<String> alDenied = map.get(PackageManager.PERMISSION_DENIED);
  301.  
  302. if(alDenied.size()>0){
  303. //convert from ArrayList<String> to String[]
  304. String[] aDenied = new String[alDenied.size()];
  305. alDenied.toArray(aDenied);
  306. this.mActivity.requestPermissions(
  307. //alDenied, //invalid syntax , because String[] is expected
  308. aDenied,
  309. piCallBackCodeForWhenTheUserResponds
  310. );
  311. }//if
  312.  
  313. }//requestNecessaryPermissionsNotYetGranted
  314.  
  315. /*
  316. receives a list of necessary permissions
  317. returns a String which states the status of each necessary permission
  318. */
  319. public String permissionsStatusToString(
  320. String[] paNecessaryPermissions
  321. ){
  322. String strRet = "";
  323.  
  324. Map<Integer, ArrayList<String>> map =
  325. this.identifyPermissionsGrantedAndDenied(paNecessaryPermissions);
  326.  
  327. ArrayList<String> alGranted =
  328. map.get(PackageManager.PERMISSION_GRANTED);
  329. ArrayList<String> alDenied =
  330. map.get(PackageManager.PERMISSION_DENIED);
  331.  
  332. strRet+="GRANTED:\n";
  333. for(String spg : alGranted) strRet+=spg+"\n";
  334.  
  335. strRet+="\n";
  336. strRet+="DENIED:\n";
  337. for(String spd : alDenied) strRet+=spd+"\n";
  338.  
  339. return strRet;
  340. }//permissionsStatusToString
  341.  
  342. public void populateSpinnerWithOptions(
  343. Spinner pSpn,
  344. String[] pOptions
  345. ){
  346. if (pSpn!=null && pOptions!=null && pOptions.length>0){
  347. ArrayAdapter<String> ad = new ArrayAdapter<>(
  348. this.mActivity,
  349. android.R.layout.simple_spinner_item,
  350. pOptions
  351. );
  352. ad.setDropDownViewResource(
  353. android.R.layout.simple_spinner_dropdown_item
  354. );
  355. pSpn.setAdapter(ad);
  356. ad.notifyDataSetChanged();
  357. }
  358. }
  359.  
  360. public static String CalendarToString(
  361. Calendar pC
  362. ){
  363. String strRet = "";
  364.  
  365. int year, month, day, hour, minutes, seconds;
  366. year = pC.get(Calendar.YEAR);
  367. month = pC.get(Calendar.MONTH)+1;
  368. day = pC.get(Calendar.DATE);
  369. hour = pC.get(Calendar.HOUR_OF_DAY);//CTRL^Q
  370. minutes = pC.get(Calendar.MINUTE);
  371. seconds = pC.get(Calendar.SECOND);
  372.  
  373. String strYear, strMonth, strDay,
  374. strHour, strMinutes, strSeconds;
  375.  
  376. strYear = String.valueOf(year);
  377. strMonth = AmUtil.addZeroIfNeededForHaving2Digits(month);
  378. strDay = AmUtil.addZeroIfNeededForHaving2Digits(day);
  379. strHour = AmUtil.addZeroIfNeededForHaving2Digits(hour);
  380. strMinutes = AmUtil.addZeroIfNeededForHaving2Digits(minutes);
  381. strSeconds = AmUtil.addZeroIfNeededForHaving2Digits(seconds);
  382.  
  383. strRet = String.format(
  384. "%s-%s-%s %s:%s:%s",
  385. strYear,
  386. strMonth,
  387. strDay,
  388. strHour,
  389. strMinutes,
  390. strSeconds
  391. );
  392.  
  393. return strRet;
  394. }//CalendarToString
  395.  
  396. public static Calendar CalendarFromString(
  397. String pStrCalendar //Y-M-D hh:mm:ss
  398. ) throws Exception //consequence: use try{}catch{Exception e} at the caller
  399. {
  400. Calendar ret = Calendar.getInstance();
  401. ret.clear();
  402.  
  403. int year, month, day, hour, minutes, seconds;
  404.  
  405. //TODO: init year .. seconds
  406. String[] aCalendarParts = pStrCalendar.split(" ");
  407. boolean bCaution = aCalendarParts.length==2;
  408. if (bCaution){
  409. String strDate = aCalendarParts[0];
  410. String strTime = aCalendarParts[1];
  411.  
  412. String[] aDateParts = strDate.split("-");
  413. String[] aTimeParts = strTime.split(":");
  414. boolean bSecondCaution = aDateParts.length==3 && aTimeParts.length==3;
  415. if (bSecondCaution){
  416. try {
  417. year = Integer.parseInt(aDateParts[0]);
  418. month = Integer.parseInt(aDateParts[1]);
  419. day = Integer.parseInt(aDateParts[2]);
  420.  
  421. hour = Integer.parseInt(aTimeParts[0]);
  422. minutes = Integer.parseInt(aTimeParts[1]);
  423. seconds = Integer.parseInt(aTimeParts[2]);
  424.  
  425. ret.set(Calendar.YEAR, year);
  426. ret.set(Calendar.MONTH, month-1);
  427. ret.set(Calendar.DATE, day);
  428. ret.set(Calendar.HOUR_OF_DAY, hour);
  429. ret.set(Calendar.MINUTE, minutes);
  430. ret.set(Calendar.SECOND, seconds);
  431.  
  432. return ret;
  433. }//try
  434. catch(Exception e){
  435. //failure in extracting numbers from the date or the time
  436. String strError = e.getMessage().toString();
  437. Log.e(TAG_AM_UTIL, strError);
  438. }//catch
  439. }//if second caution
  440. }//if first caution
  441.  
  442. String strError = "Could NOT parse Calendar string!";
  443. Log.e(TAG_AM_UTIL, strError);
  444. throw new Exception(strError);
  445.  
  446. //return null; //never happens
  447. }//CalendarFromString
  448.  
  449. public static int randomInt(
  450. int pMin,
  451. int pMax
  452. ){
  453. Random r = new Random();
  454. int iMax = Math.max(pMin, pMax);
  455. int iMin = Math.min(pMin, pMax);
  456. int iAmplitude = iMax-iMin+1;
  457. int iJump = r.nextInt(iAmplitude);
  458. int iDest = iMin+ iJump;
  459. return iDest;
  460. }//randomInt
  461.  
  462. private static String
  463. addZeroIfNeededForHaving2Digits(
  464. int pSomeNumber
  465. )
  466. {
  467. if (pSomeNumber<10)
  468. return "0"+pSomeNumber;
  469. else
  470. return String.valueOf(pSomeNumber);
  471. }//addZeroIfNeededForHaving2Digits
  472.  
  473. public static enum COMPARISON_TYPES {
  474. COMPARE_TYPE_EXACT_MATCH_CASE_SENSITIVE,
  475. COMPARE_TYPE_EXACT_MATCH_CASE_INSENSITIVE,
  476. COMPARE_TYPE_CONTAINS_CASE_SENSITIVE,
  477. COMPARE_TYPE_CONTAINS_CASE_INSENSITIVE,
  478. }
  479.  
  480. public static int arrayStringContainsElement(
  481. String[] pA,
  482. String pE,
  483. COMPARISON_TYPES pComparisonType
  484. ){
  485. if (pA!=null){
  486. int iHowMany = pA.length;
  487. for (int idx=0; idx<iHowMany; idx++){
  488. String strCurrent = pA[idx];
  489. boolean bMatchCaseInsensitive = strCurrent.equalsIgnoreCase(pE);
  490. boolean bMatchCaseSensitive = strCurrent.equals(pE);
  491. boolean bMatchContainsCaseSensitive = strCurrent.indexOf(pE)!=-1;
  492. boolean bMatchContainsCaseInsensitive = strCurrent.toLowerCase().indexOf(pE.toLowerCase())!=-1;
  493.  
  494. boolean bMatch = false;
  495. switch (pComparisonType){
  496. case COMPARE_TYPE_EXACT_MATCH_CASE_INSENSITIVE:
  497. bMatch = bMatchCaseInsensitive;
  498. break;
  499. case COMPARE_TYPE_EXACT_MATCH_CASE_SENSITIVE:
  500. bMatch = bMatchCaseSensitive;
  501. break;
  502. case COMPARE_TYPE_CONTAINS_CASE_SENSITIVE:
  503. bMatch = bMatchContainsCaseSensitive;
  504. break;
  505. case COMPARE_TYPE_CONTAINS_CASE_INSENSITIVE:
  506. bMatch = bMatchContainsCaseInsensitive;
  507. break;
  508. }//switch
  509.  
  510. if (bMatch) return idx;
  511. }
  512. }
  513. return -1;
  514. }//arrayStringContainsElement
  515.  
  516. public static Float readFloatFromEditText (EditText pEt) throws Exception {
  517. if (pEt!=null){
  518. String strEt = pEt.getText().toString().trim();
  519. try{
  520. float f = Float.parseFloat(strEt);
  521. return f;
  522. }
  523. catch (Exception e){
  524. throw (e);
  525. }
  526. }//if
  527. else{
  528. throw new Exception("No EditText");
  529. }//else
  530. }//readFloatFromEditText
  531.  
  532. public static int readIntFromEt (
  533. EditText pEt
  534. ) throws Exception
  535. {
  536. if (pEt!=null){
  537. String strEt =
  538. pEt.getText().toString().trim();
  539.  
  540. Boolean bEmptyString = strEt.isEmpty();
  541.  
  542. if (bEmptyString){
  543. //cannot extract int from empty string
  544. throw new Exception (AmUtil.E_EMPTY_STRING);
  545. }//if
  546. else{
  547. try {
  548. int i = Integer.parseInt(strEt);
  549. return i;
  550. }//try
  551. catch (Exception e){
  552. throw new Exception
  553. (AmUtil.E_CANNOT_PARSE_INT_FROM_STRING);
  554. }//catch
  555. }//else
  556. }//if we have a valid EditText
  557. else{
  558. throw new Exception
  559. (AmUtil.E_NO_EDITTEXT);
  560. }//else
  561. }//readIntFromEt
  562.  
  563. /*
  564. receives the name of a file, located in the "private internal storage"
  565. returns the entire text content of that file
  566. */
  567. public String genericPrivateInternalStorageFileReader(
  568. String pFileName
  569. ){
  570. String strAll = "";
  571. try{
  572. FileInputStream fis = mActivity.openFileInput(
  573. pFileName
  574. );
  575. if (fis!=null){
  576. InputStreamReader isr = new InputStreamReader(
  577. fis,
  578. StandardCharsets.UTF_8
  579. );
  580. char c; int i;
  581. final int END_OF_FILE = -1;
  582. while ((i=isr.read())!=END_OF_FILE){
  583. c = (char)i; //cast the byte to a char
  584. strAll+=c; //concatenate the char to the already read file contents
  585. }//while
  586. isr.close();
  587. }//if
  588. fis.close();
  589. }//try
  590. catch(Exception e){
  591. /*
  592. e.g. : file does not exist
  593. */
  594. Log.e(TAG_AM_UTIL, e.getMessage().toString());
  595. }//catch
  596. return strAll;
  597. }//genericPrivateInternalStorageFileReader
  598.  
  599. /*
  600. receives a file name and the content, to be written into the "private internal storage"
  601. returns true on success, false on failure
  602. */
  603. public boolean genericPrivateInternalStorageFileWriter(
  604. String pFileName,
  605. String... pContent
  606. ){
  607. try {
  608. FileOutputStream fos =
  609. mActivity.openFileOutput(pFileName, Activity.MODE_PRIVATE);
  610.  
  611. if (fos!=null){
  612. OutputStreamWriter osw = new OutputStreamWriter(
  613. fos,
  614. StandardCharsets.UTF_8
  615. );
  616. for (String strPartial : pContent){
  617. osw.write(strPartial);
  618. }//for
  619. osw.close();
  620. }//if
  621. fos.close();
  622.  
  623. return true;
  624. }//try
  625. catch (Exception e){
  626. Log.e(TAG_AM_UTIL, e.getMessage().toString());
  627. return false;
  628. }//catch
  629. }//genericPrivateInternalStorageFileWriter
  630.  
  631. /*
  632. receives the text for an about to be created new Button
  633. receives the already existing LinearLayout where the dyn created Button
  634. is to be added
  635. receives an already existing click listener to be assigned to the
  636. about to be created new Button
  637. */
  638. void createNewButtonInLinearLayout (
  639. String pStrButtonText, //text for the new Button
  640. LinearLayout pLayoutWhereToAddTheNewButton, //LL where to add the Button (can NOT be null)
  641. Button.OnClickListener pButtonClickHandler //object that handles the behavior for the new Button
  642. )
  643. {
  644. Button btnNewNumber = new Button(mActivity);
  645. btnNewNumber.setText(pStrButtonText);
  646. LinearLayout.LayoutParams wh = new LinearLayout.LayoutParams(
  647. ViewGroup.LayoutParams.MATCH_PARENT,
  648. ViewGroup.LayoutParams.WRAP_CONTENT
  649. );
  650. btnNewNumber.setLayoutParams(wh);
  651. btnNewNumber.setOnClickListener(pButtonClickHandler);
  652.  
  653. pLayoutWhereToAddTheNewButton.addView(btnNewNumber);
  654. }//createNewButtonInLinearLayout
  655.  
  656. public void actionQuit(){
  657. Intent intentQuitToMain = new Intent(Intent.ACTION_MAIN);
  658. intentQuitToMain.addCategory(Intent.CATEGORY_HOME);
  659. intentQuitToMain.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  660. mActivity.startActivity(intentQuitToMain);
  661. mActivity.finish();
  662. }//actionQuit
  663.  
  664.  
  665. public static String io_https_ReadAll(
  666. String pUrl
  667. ){
  668. String ret="";
  669. HttpURLConnection urlConnection = null;
  670. try {
  671. URL url = new URL(pUrl);
  672.  
  673. urlConnection = (HttpsURLConnection) url.openConnection();
  674. InputStream in = urlConnection.getInputStream();
  675. InputStreamReader isr = new InputStreamReader(in);
  676. BufferedReader br = new BufferedReader(isr);
  677.  
  678. /*
  679. //this would eliminate the new line separators
  680. String strLine = "";
  681. while ((strLine = br.readLine())!=null){
  682. ret+=strLine;
  683. }
  684. */
  685.  
  686. int i;
  687. while((i=br.read())!=-1){
  688. char c = (char) i;
  689. ret+=c;
  690. }//while
  691.  
  692. br.close();
  693. isr.close();
  694. in.close();
  695. } catch (Exception e) {
  696. e.printStackTrace();
  697. } finally //The finally block always executes when the try block exits
  698. {
  699. if (urlConnection != null) {
  700. urlConnection.disconnect();
  701. }//if
  702. }//finally
  703. return ret;
  704. }//io_https_ReadAll
  705.  
  706. }//AmUtil
  707.  
  708. //
  709.  
  710. package com.joythis.android.textcapturer;
  711.  
  712. import androidx.annotation.NonNull;
  713. import androidx.appcompat.app.AppCompatActivity;
  714.  
  715. import android.content.Context;
  716. import android.content.Intent;
  717. import android.graphics.Bitmap;
  718. import android.net.Uri;
  719. import android.os.AsyncTask;
  720. import android.os.Bundle;
  721. import android.util.Log;
  722. import android.view.Menu;
  723. import android.view.MenuInflater;
  724. import android.view.MenuItem;
  725. import android.view.View;
  726. import android.widget.ArrayAdapter;
  727. import android.widget.ImageView;
  728. import android.widget.LinearLayout;
  729. import android.widget.ListView;
  730. import android.widget.TextView;
  731. import android.widget.Toast;
  732.  
  733. import java.io.File;
  734. import java.io.FileInputStream;
  735. import java.io.FileOutputStream;
  736. import java.io.InputStreamReader;
  737. import java.io.OutputStreamWriter;
  738. import java.nio.charset.StandardCharsets;
  739. import java.util.ArrayList;
  740. import java.util.Calendar;
  741. import java.util.HashMap;
  742. import java.util.Map;
  743.  
  744. public class MainActivity extends AppCompatActivity {
  745. Context mContext;
  746. TextView mTvAbout, mTvCapturedText;
  747. ImageView mIvCapturedImage;
  748.  
  749. ArrayList<String> mAlRecords;
  750. ArrayAdapter<String> mAd;
  751. ListView mLvRecords;
  752.  
  753. class MyTaskToReadRemoteImageAndDisplayItOnAnImageView
  754. extends AsyncTask<
  755. String, //because the argument required for the task to execute, is an URL (a string)
  756. Void, //because I will not be doing progress control
  757. Bitmap //because the result of whatever will happen in background is a Bitmap
  758. >
  759. {
  760.  
  761. /*
  762. in "doInBackground" code whatever can NOT run in the main thread
  763. */
  764. @Override
  765. protected Bitmap doInBackground(String... strings) {
  766. String strUrl = strings[0];
  767. Bitmap bitmapThatCorrespondsToTheRemoteImage =
  768. AmIoHttp.readBitmapFromUrl(strUrl);
  769. return bitmapThatCorrespondsToTheRemoteImage;
  770. //return null;
  771. }//doInBackground
  772.  
  773. /*
  774. code whatever you want to do AFTER the background code ends
  775. */
  776. @Override
  777. protected void onPostExecute(Bitmap bitmap) {
  778. mIvCapturedImage.setImageBitmap(bitmap);
  779. super.onPostExecute(bitmap);
  780. }//onPostExecute
  781. }//MyTaskToReadRemoteImageAndDisplayItOnAnImageView
  782.  
  783.  
  784. //attaches the menu to the Activity
  785. @Override
  786. public boolean onCreateOptionsMenu(Menu pMenu) {
  787. MenuInflater minf = getMenuInflater();
  788. minf.inflate(
  789. R.menu.my_menu,
  790. pMenu
  791. );
  792. return super.onCreateOptionsMenu(pMenu);
  793. }//onCreateOptionsMenu
  794.  
  795. //code the behavior of each menu item
  796. /*
  797. code that processes the user interface, always runs in the "Main Thread"
  798. nothing more should run on the main thread
  799. above all, code that depends on external resources should NOT
  800. run directly in the main thread
  801. */
  802. @Override
  803. public boolean onOptionsItemSelected(
  804. @NonNull MenuItem pItem
  805. )
  806. {
  807. switch(pItem.getItemId()){
  808. case R.id.idMenuItemExampleLoadImageFromUrl:
  809. //https://arturmarques.com/edu/ddm/ddm.png
  810. String strTestUrl =
  811. "https://arturmarques.com/edu/ddm/ddm.png";
  812.  
  813. //can NOT work because it would run on the main thread
  814. /*
  815. loadImageAtUrlToImageView(
  816. strTestUrl, //URL for some image
  817. mIvCapturedImage //an ImageView object
  818. );
  819. */
  820.  
  821. //can work because it happens in its thread, asynchronously
  822. MyTaskToReadRemoteImageAndDisplayItOnAnImageView t = new
  823. MyTaskToReadRemoteImageAndDisplayItOnAnImageView();
  824. t.execute(strTestUrl);
  825.  
  826. break;
  827. }//switch
  828.  
  829. return super.onOptionsItemSelected(pItem);
  830. }//onOptionsItemSelected
  831.  
  832. void loadImageAtUrlToImageView (
  833. String pUrl,
  834. ImageView pImageViewThatWillDisplayTheImageAtTheUrl
  835. ){
  836. Bitmap bitmap = AmIoHttp.readBitmapFromUrl(pUrl);
  837. pImageViewThatWillDisplayTheImageAtTheUrl.
  838. setImageBitmap(bitmap);
  839. }//loadImageAtUrlToImageView
  840.  
  841. public final static String MY_TSV_DB = "SHARES.DB";
  842.  
  843. @Override
  844. protected void onCreate(Bundle savedInstanceState) {
  845. super.onCreate(savedInstanceState);
  846. setContentView(R.layout.activity_main);
  847.  
  848. init();
  849. }//onCreate
  850.  
  851. boolean qualityControl(
  852. Object[] pCheckThese
  853. ){
  854. boolean bRet = true;
  855. for (Object o : pCheckThese){
  856. bRet = bRet && (o!=null);
  857. }//for
  858.  
  859. return bRet;
  860. }//qualityControl
  861.  
  862. Map<Object, Boolean> altQualityControl(
  863. Object[] pCheckThese
  864. ){
  865. Map<Object, Boolean> aRet= new HashMap<>();
  866. for (Object o : pCheckThese){
  867. boolean bOk = o!=null;
  868. aRet.put(o, bOk);
  869. }//for
  870. return aRet;
  871. }//altQualityControl
  872.  
  873. void init(){
  874. mContext = this;
  875. mTvAbout = findViewById(R.id.idTvAbout);
  876. mTvCapturedText = findViewById(R.id.idTvCapturedText);
  877. mIvCapturedImage = findViewById(R.id.idIvCapturedImage);
  878.  
  879. mLvRecords = findViewById(R.id.idLvRecords);
  880. mAlRecords = new ArrayList<>();
  881. mAd = new ArrayAdapter<>(
  882. mContext,
  883. android.R.layout.simple_list_item_1,
  884. mAlRecords //memory address for the data
  885. );
  886. mLvRecords.setAdapter(mAd);
  887.  
  888. Object[] aRelevant = {mTvAbout, mTvCapturedText};
  889. boolean bCanProceed = qualityControl(aRelevant);
  890.  
  891. if (!bCanProceed){
  892. Toast t = Toast.makeText(
  893. this,
  894. getString(R.string.strThereIsNullObject),
  895. Toast.LENGTH_LONG
  896. );
  897. return;
  898. }//if
  899.  
  900. mTvAbout.setText(
  901. whereIsThePrivateInternalStorage()
  902. +"\nText Captured:"
  903. );
  904.  
  905. /*
  906. TODO: avoid reprocessing the Intent on reexecutions of onCreate
  907. */
  908. checkIfCalledForSharingAndDisplayingSharedData();
  909.  
  910. refresh();
  911. }//init
  912.  
  913. void checkIfCalledForSharingAndDisplayingSharedData(){
  914. Intent intentHowWasICalled = getIntent();
  915.  
  916. if (intentHowWasICalled!=null){
  917. String strAction =
  918. intentHowWasICalled.getAction();
  919.  
  920. //share
  921. boolean bIWantToAnswer =
  922. strAction.equals(Intent.ACTION_SEND);
  923.  
  924. boolean bIWantToAnswer2 =
  925. strAction.compareTo(Intent.ACTION_SEND)==0;
  926.  
  927. boolean bIWantToAnswer3 =
  928. strAction.compareToIgnoreCase(Intent.ACTION_SEND)==0;
  929.  
  930. if (bIWantToAnswer){
  931. //it was a share!
  932.  
  933. String strType =
  934. intentHowWasICalled.getType();
  935.  
  936. Toast.makeText(
  937. mContext,
  938. strType,
  939. Toast.LENGTH_LONG
  940. ).show(); //"image/png" "image/jpeg"
  941.  
  942. boolean bIsText =
  943. strType.startsWith("text/");
  944.  
  945. boolean bIsImage =
  946. strType.startsWith("image/");
  947.  
  948. if (bIsText){
  949. String strTextThatWasShared =
  950. intentHowWasICalled.getStringExtra(
  951. Intent.EXTRA_TEXT
  952. );
  953.  
  954. insert(strTextThatWasShared); //record the received text
  955. refresh(); //shows the text
  956.  
  957. mTvCapturedText.setVisibility(View.GONE); //hides the TextView
  958.  
  959. //enough for principle demonstration
  960. mTvCapturedText.setText(
  961. strTextThatWasShared
  962. );
  963. }//if text was shared
  964. else
  965. if (bIsImage){
  966. //content://saksçdlkaslçdkasdlçakd
  967. Uri uriForTheReceivedImage =
  968. intentHowWasICalled.getParcelableExtra(
  969. Intent.EXTRA_STREAM
  970. );
  971. if (uriForTheReceivedImage!=null){
  972. mIvCapturedImage.setImageURI(
  973. uriForTheReceivedImage
  974. );
  975. }//if
  976. }//if
  977. }//if the Activity was called from an ACTION_SEND Intent (e.g. Share from another app)
  978. }//if got an Intent object with all the necessary data
  979. }//checkIfCalledForSharingAndDisplaySharedText
  980.  
  981. void dynAddObjsToLayout(
  982. LinearLayout pL,
  983. Uri pImgSource
  984. ){
  985. ImageView iv = new ImageView(mContext);
  986. iv.setImageURI(pImgSource);
  987. iv.setContentDescription("Bla bla bla");
  988. pL.addView(iv);
  989. }
  990.  
  991. void refresh(){
  992. /*
  993. String strNewContent = readFile(MY_TSV_DB);
  994. mTvCapturedText.setText(strNewContent);
  995. */
  996. //mAlRecords = new ArrayList<>(); //NO GO! would break the Adapter
  997. mAlRecords.clear();
  998.  
  999. //mAlRecords.addAll(readFile(MY_TSV_DB)); //original order
  1000. ArrayList<String> alTemp = readFile(MY_TSV_DB);
  1001. for (int idx=0; idx<alTemp.size(); idx++){
  1002. String strContent = alTemp.get(idx);
  1003. mAlRecords.add(0, strContent);
  1004. }//for
  1005.  
  1006. mAd.notifyDataSetChanged();
  1007. }//refresh
  1008.  
  1009. /*String*/ArrayList<String> readFile(
  1010. String pFileName
  1011. ){
  1012. String strContent =
  1013. readFromPrivateInternalStorage(pFileName);
  1014.  
  1015. /*
  1016. somewhat useless while the app is not rewritten using
  1017. a true "Record" class data type
  1018. and a collection of Records is kept (for example in ArrayList<Record>)
  1019. */
  1020. ArrayList<String> aRet = new ArrayList<>();
  1021. String[] aRecords =
  1022. strContent.split("\n");
  1023. for(String record : aRecords){
  1024. String strAfterReplacement =
  1025. record.replace(
  1026. "<br>", "\n"
  1027. );
  1028. aRet.add(strAfterReplacement);
  1029. }//for
  1030. return aRet;
  1031.  
  1032. //return strContent;
  1033. }//readFile
  1034.  
  1035. /*
  1036. will record with a TSV structure of our imagination
  1037. the data in a file, in the private internal storage of the app
  1038.  
  1039. <when> \t <text> \n
  1040. */
  1041. void insert(String pStrWhatToInsert){
  1042. Calendar cal = Calendar.getInstance();
  1043. String strYMD = String.format(
  1044. "%d-%d-%d",
  1045. cal.get(Calendar.YEAR),
  1046. (cal.get(Calendar.MONTH)+1),
  1047. cal.get(Calendar.DAY_OF_MONTH)
  1048. );
  1049.  
  1050. //replace the TSV reserved-symbols for innocuos alternatives
  1051. // \n -> "<br>" ; \t -> " "
  1052. String strAfterReplacement =
  1053. pStrWhatToInsert.replace(
  1054. "\n",
  1055. "<br>"
  1056. );
  1057.  
  1058. strAfterReplacement =
  1059. pStrWhatToInsert.replace(
  1060. "\t",
  1061. " "
  1062. );
  1063.  
  1064. String strRecord = String.format(
  1065. "%s\t%s\n",
  1066. strYMD,
  1067. strAfterReplacement
  1068. );
  1069.  
  1070. Boolean bOK =
  1071. writeToPrivateInternalStorage(
  1072. MY_TSV_DB,
  1073. //pStrWhatToInsert+"\n",
  1074. strRecord,
  1075. MODE_APPEND
  1076. );
  1077.  
  1078. if (bOK){
  1079. Toast t = Toast.makeText(
  1080. mContext,
  1081. "New record added to TSV DB",
  1082. Toast.LENGTH_LONG
  1083. );
  1084. t.show();
  1085. }//if
  1086. }//insert
  1087.  
  1088. /*
  1089. to read and write in the Private Internal Storage
  1090. we need tools for dumping and recovering text from
  1091. that exclusive non-volatile file-system area
  1092. */
  1093.  
  1094. String whereIsThePrivateInternalStorage(){
  1095. File pis = this.getFilesDir();
  1096. return pis.getAbsolutePath();
  1097. }//whereIsThePrivateInternalStorage
  1098.  
  1099. Boolean writeToPrivateInternalStorage(
  1100. String pFileName,
  1101. String pFileContent,
  1102. int pWriteMode //PRIVATE (destructive) / APPEND (cumulative)
  1103. ){
  1104. try {
  1105. FileOutputStream fos = openFileOutput(
  1106. pFileName,
  1107. //MODE_APPEND
  1108. pWriteMode
  1109. );
  1110.  
  1111. if (fos!=null){
  1112. OutputStreamWriter osw = new OutputStreamWriter(
  1113. fos,
  1114. StandardCharsets.UTF_8
  1115. );
  1116. if (osw!=null){
  1117. osw.write(pFileContent);
  1118. osw.close();
  1119. fos.close();
  1120. return true;
  1121. }//if
  1122. }//if
  1123. }//try
  1124. catch (Exception e){
  1125. Log.e(
  1126. getClass().getName(),
  1127. e.toString()
  1128. );
  1129. }//catch
  1130. return false;
  1131. }//writeToPrivateInternalStorage
  1132.  
  1133. String readFromPrivateInternalStorage(
  1134. String pFileName
  1135. ){
  1136. try{
  1137. FileInputStream fis = this.openFileInput(pFileName);
  1138. if (fis!=null){
  1139. InputStreamReader isr = new InputStreamReader(
  1140. fis,
  1141. StandardCharsets.UTF_8
  1142. );
  1143.  
  1144. if (isr!=null){
  1145. int i; char c; String strAll="";
  1146. while ((i=isr.read())!=-1){
  1147. c = (char) i;
  1148. strAll+=c;
  1149. }//while
  1150. isr.close();
  1151. fis.close();
  1152.  
  1153. return strAll;
  1154. }//if
  1155. }//if
  1156. }//try
  1157. catch(Exception e){
  1158. Log.e(
  1159. getClass().getName(),
  1160. e.toString()
  1161. );
  1162. }//catch
  1163.  
  1164. return "";
  1165. }//readFromPrivateInternalStorage
  1166. }//MainActivity
  1167.  
  1168.  
  1169. //
  1170.  
  1171. 1 - layout LL RL CL
  1172. 2 - init / assocs / behavior
  1173. 3 - depende avaliar competência extra relacionada com o comportamento
  1174. 4 - storage : ficheiros ou SQLite
  1175. 5 - capacidade criativa
  1176.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement