am_dot_com

DDM 20201203

Dec 3rd, 2020 (edited)
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 19.19 KB | None | 0 0
  1. package com.joythis.android.myphonecaller;
  2.  
  3. import android.Manifest;
  4. import android.app.Activity;
  5. import android.content.Intent;
  6. import android.content.pm.PackageManager;
  7. import android.net.Uri;
  8. import android.util.Log;
  9. import android.widget.Toast;
  10.  
  11. import androidx.core.content.ContextCompat;
  12.  
  13. import java.net.URI;
  14. import java.util.ArrayList;
  15. import java.util.HashMap;
  16. import java.util.Map;
  17.  
  18. public class AmUtil {
  19.     Activity mActivity;
  20.  
  21.     public AmUtil(Activity pA){
  22.         this.mActivity = pA;
  23.     }//AmUtil
  24.  
  25.     public void fb(
  26.         String pStrMsg
  27.     ){
  28.         Toast t = Toast.makeText(
  29.             this.mActivity,
  30.             pStrMsg,
  31.             Toast.LENGTH_LONG
  32.         );
  33.         t.show();
  34.     }//fb
  35.  
  36.     public void phoneTo(
  37.         String pStrPhoneNumber
  38.     ){
  39.         try {
  40.             Uri uriForPhoneNumber = Uri.parse("tel:" + pStrPhoneNumber);
  41.  
  42.             Intent intentForMakingThePhoneCall =
  43.                 new Intent(
  44.                     Intent.ACTION_CALL
  45.                 );
  46.  
  47.             intentForMakingThePhoneCall.setData(
  48.                 uriForPhoneNumber
  49.             );
  50.  
  51.             boolean bUserAuthorizedTheAppToMakePhoneCalls =
  52.                 ContextCompat.checkSelfPermission(
  53.                     mActivity,
  54.                     Manifest.permission.CALL_PHONE
  55.                 ) == PackageManager.PERMISSION_GRANTED;
  56.  
  57.             if (bUserAuthorizedTheAppToMakePhoneCalls) {
  58.                 this.mActivity.startActivity(
  59.                     intentForMakingThePhoneCall
  60.                 );
  61.             }
  62.             else{
  63.                 boolean bUserAcceptsExplanationsOnWhyThePermissionIsImportant =
  64.                     mActivity.shouldShowRequestPermissionRationale(
  65.                         Manifest.permission.CALL_PHONE
  66.                     );
  67.                 if (bUserAcceptsExplanationsOnWhyThePermissionIsImportant){
  68.                     fb("Without this permission, the app can NOT make phone calls.");
  69.                 }
  70.             }
  71.         }//try
  72.         catch(Exception e){
  73.             Log.e(
  74.                getClass().getName(),
  75.                e.toString()
  76.             );
  77.         }//catch
  78.     }//phoneTo
  79.  
  80.     public Map<Integer, ArrayList<String>>
  81.         identifyPermissionsGrantedAndDenied(
  82.             String[] paNecessaryPermissions
  83.     )
  84.     {
  85.         Map<Integer, ArrayList<String>> retMap = new HashMap<>();
  86.         ArrayList<String> alGranted = new ArrayList<>();
  87.         ArrayList<String> alDenied = new ArrayList<>();
  88.  
  89.         for (String permission : paNecessaryPermissions){
  90.             boolean bGranted =
  91.                 ContextCompat.checkSelfPermission(
  92.                     mActivity,
  93.                     permission
  94.                 ) == PackageManager.PERMISSION_GRANTED;
  95.  
  96.             boolean bDenied =
  97.                     ContextCompat.checkSelfPermission(
  98.                             mActivity,
  99.                             permission
  100.                     ) == PackageManager.PERMISSION_DENIED;
  101.  
  102.             if (bGranted) alGranted.add(permission);
  103.             if (bDenied) alDenied.add(permission);
  104.         }//for
  105.  
  106.         retMap.put(/* Integer 0 */ PackageManager.PERMISSION_GRANTED, alGranted);
  107.         retMap.put(/* Integer -1 */ PackageManager.PERMISSION_DENIED, alDenied);
  108.  
  109.         return retMap;
  110.     }//identifyPermissionsGrantedAndDenied
  111.  
  112.     public void requestNecessaryPermissionsNotYetGranted(
  113.         String[] paNecessaryPermissions,
  114.         int piCallBackCodeForWhenTheUserResponds
  115.     ){
  116.         /*
  117.         do not request permissions already granted
  118.          */
  119.  
  120.  
  121.     }//requestNecessaryPermissionsNotYetGranted
  122.  
  123. }
  124. //**
  125.  
  126. package com.joythis.android.myphonecaller;
  127.  
  128. import android.content.ContentValues;
  129. import android.content.Context;
  130. import android.database.Cursor;
  131. import android.database.sqlite.SQLiteDatabase;
  132. import android.database.sqlite.SQLiteOpenHelper;
  133. import android.util.Log;
  134.  
  135. import androidx.annotation.Nullable;
  136.  
  137. import java.util.ArrayList;
  138.  
  139. /*
  140. for the non-volatile representation of "contacts"
  141. following the framework, regarding inheritance from
  142. SQLiteOpenHelper
  143.  */
  144.  
  145. //1 - assume the inheritance
  146. public class ContactDB extends SQLiteOpenHelper{
  147.  
  148.     public final static String DB_NAME = "contacts.db";
  149.     public final static int DB_VERSION = 4;
  150.  
  151.     //create constants for all table and column names
  152.     public final static String TABLE_CONTACTS = "tContacts";
  153.     public final static String COL_ID = "_id";
  154.     public final static String COL_NAME = "cName";
  155.     public final static String COL_NUMBER = "cNumber";
  156.  
  157.     /*
  158.     CREATE TABLE IF NOT EXISTS tContacts(
  159.     _id INTEGER PRIMARY KEY AUTOINCREMENT,
  160.     cName TEXT NOT NULL,
  161.     cNumber TEXT NOT NULL
  162.     );
  163.      */
  164.     public final static String CREATE_TABLE_CONTACTS =
  165.     "CREATE TABLE IF NOT EXISTS "+TABLE_CONTACTS+"(\n"+
  166.     COL_ID+" INTEGER PRIMARY KEY NOT NULL, \n"+
  167.     COL_NAME+" TEXT NOT NULL, \n"+
  168.     COL_NUMBER+" TEXT NOT NULL\n"+
  169.     ");";
  170.  
  171.     /*
  172.     DROP TABLE IF EXISTS tContacts;
  173.      */
  174.     public final static String DROP_TABLE_CONTACTS =
  175.     "DROP TABLE IF EXISTS "+TABLE_CONTACTS+";";
  176.  
  177.     public ContactDB(
  178.         Context pContext
  179.     ){
  180.         super(
  181.             pContext,
  182.             DB_NAME,
  183.             null,
  184.             DB_VERSION
  185.         );
  186.     }//ContactDB
  187.  
  188.     public ContactDB(
  189.         @Nullable Context context,
  190.         @Nullable String name,
  191.         @Nullable SQLiteDatabase.CursorFactory factory,
  192.         int version
  193.     ){
  194.         super(context, name, factory, version);
  195.     }//ContactDB
  196.  
  197.     void installDB(
  198.         SQLiteDatabase pDB
  199.     ){
  200.         if (pDB!=null){
  201.             try{
  202.                 pDB.execSQL(
  203.                         CREATE_TABLE_CONTACTS
  204.                 );
  205.             }//try
  206.             catch (Exception e){
  207.                 Log.e(
  208.                   getClass().getName(),
  209.                   e.toString()
  210.                 );
  211.             }//catch
  212.         }//if
  213.     }//installDB
  214.  
  215.     /*
  216.     will be AUTOMATICALLY called upon the first need to
  217.     use the database; e.g. upon the first "insert", or the
  218.     first "select".
  219.     The developer will NEVER, EVER, call this method directly.
  220.      */
  221.     //2
  222.     @Override
  223.     public void onCreate(SQLiteDatabase db) {
  224.         //perform database installation here
  225.         installDB(db);
  226.     }//onCreate
  227.  
  228.     /*
  229.     will be AUTOMATICALLY called
  230.      */
  231.     //2
  232.     @Override
  233.     public void onUpgrade(
  234.         SQLiteDatabase db,
  235.         int oldVersion,
  236.         int newVersion
  237.     )
  238.     {
  239.         if (db!=null){
  240.             //upgrade/change the database infrastructure here
  241.             if (newVersion > oldVersion){
  242.                 //destroy the current infrastructure7
  243.                 //TODO: backup of the previous data
  244.                 try {
  245.                     db.execSQL(DROP_TABLE_CONTACTS);
  246.                 }//try
  247.                 catch(Exception e){
  248.                     Log.e(
  249.                         getClass().getName(),
  250.                         e.toString()
  251.                     );
  252.                 }//catch
  253.                 installDB(db); //rebuild using the new version of the infrastructure
  254.             }//if
  255.         }//if
  256.     }//onUpgrade
  257.  
  258.     //insertContact
  259.     /*
  260.     will return the "line" where the record is inserted
  261.      */
  262.     public final static String KEY_NAME = "KEY_NAME";
  263.     public final static String KEY_NUMBER = "KEY_NUMBER";
  264.     public long insertContact (Contact pC)
  265.     {
  266.         SQLiteDatabase db = this.getWritableDatabase();
  267.         if (db!=null){
  268.             ContentValues pairsKeyValue = new ContentValues();
  269.  
  270.             pairsKeyValue.put(
  271.                 COL_NAME,
  272.                 pC.getName()
  273.             ); //contact name
  274.             pairsKeyValue.put(
  275.                 COL_NUMBER,
  276.                 pC.getNumber()
  277.             ); //contact number
  278.  
  279.             //-1 on failure
  280.             long iRecordNumber =
  281.                 db.insert(
  282.                     TABLE_CONTACTS,
  283.                     null,
  284.                     pairsKeyValue
  285.                 );
  286.  
  287.             db.close();
  288.  
  289.             return iRecordNumber;
  290.         }//if
  291.  
  292.         return -1;
  293.     }//insertContact
  294.  
  295.     /*
  296.     public long insertContact(
  297.         String pStrName, String pStrNumber
  298.     ){
  299.  
  300.     }//insertContact
  301.  
  302.      */
  303.  
  304.     public final static String SELECT_ALL_CONTACTS_BY_NAME_ASC =
  305.         "SELECT * FROM "+TABLE_CONTACTS+" ORDER BY "+COL_NAME+" ASC;";
  306.     public final static String SELECT_ALL_CONTACTS_BY_NAME_DESC =
  307.             "SELECT * FROM "+TABLE_CONTACTS+" ORDER BY "+COL_NAME+" DESC;";
  308.  
  309.     public final static String SELECT_ALL_CONTACTS_BY_NUMBER_ASC =
  310.         "SELECT * FROM "+TABLE_CONTACTS+" ORDER BY "+COL_NUMBER+" ASC;";
  311.     public final static String SELECT_ALL_CONTACTS_BY_NUMBER_DESC =
  312.             "SELECT * FROM "+TABLE_CONTACTS+" ORDER BY "+COL_NUMBER+" DESC;";
  313.  
  314.     public final static String SELECT_ALL_CONTACTS_BY_INSERT_DATE_ASC =
  315.         "SELECT * FROM "+TABLE_CONTACTS+" ORDER BY "+COL_ID+" ASC;";
  316.     public final static String SELECT_ALL_CONTACTS_BY_INSERT_DATE_DESC =
  317.         "SELECT * FROM "+TABLE_CONTACTS+" ORDER BY "+COL_ID+" DESC;";
  318.  
  319.     public ArrayList<Contact> selectAllContactsByNameASC(){
  320.         return selectAllByQuery(SELECT_ALL_CONTACTS_BY_NAME_ASC);
  321.     }//selectAllContactsByNameASC
  322.  
  323.     public ArrayList<Contact> selectAllContactsByNameDESC(){
  324.         return selectAllByQuery(SELECT_ALL_CONTACTS_BY_NAME_DESC);
  325.     }//selectAllContactsByNameASC
  326.  
  327.     public ArrayList<Contact> selectAllContactsByNumberASC(){
  328.         return selectAllByQuery(SELECT_ALL_CONTACTS_BY_NUMBER_ASC);
  329.     }//selectAllContactsByNumberASC
  330.  
  331.     public ArrayList<Contact> selectAllContactsByNumberDESC(){
  332.         return selectAllByQuery(SELECT_ALL_CONTACTS_BY_NUMBER_DESC);
  333.     }//selectAllContactsByNumberASC
  334.  
  335.     public ArrayList<Contact> selectAllContactsByInsertDateASC(){
  336.         return selectAllByQuery(SELECT_ALL_CONTACTS_BY_INSERT_DATE_ASC);
  337.     }//selectAllContactsByNameASC
  338.  
  339.     public ArrayList<Contact> selectAllContactsByInsertDateDESC(){
  340.         return selectAllByQuery(SELECT_ALL_CONTACTS_BY_INSERT_DATE_DESC);
  341.     }//selectAllContactsByNameASC
  342.  
  343.     private ArrayList<Contact> selectAllByQuery(
  344.         String pSelectQuery
  345.     ){
  346.         ArrayList<Contact> aRet = new ArrayList<>();
  347.         boolean bCheck = pSelectQuery.length()>0;
  348.         //bCheck = !pSelectQuery.isEmpty();
  349.  
  350.         if (bCheck){
  351.             try {
  352.                 SQLiteDatabase db = getReadableDatabase();
  353.                 if (db != null) {
  354.                     Cursor cursor =
  355.                             db.rawQuery(
  356.                                     pSelectQuery,
  357.                                     null
  358.                             );
  359.  
  360.                     if (cursor != null) {
  361.                         cursor.moveToFirst();
  362.                         while (!cursor.isAfterLast()) {
  363.                             String strName =
  364.                                     cursor.getString(
  365.                                             cursor.getColumnIndex(COL_NAME)
  366.                                             //which column INDEX?
  367.                                     );
  368.                             String strNumber =
  369.                                     cursor.getString(
  370.                                             cursor.getColumnIndex(COL_NUMBER)
  371.                                             //which column INDEX?
  372.                                     );
  373.  
  374.                             Contact c = new Contact(strName, strNumber);
  375.                             aRet.add(c);
  376.  
  377.                             cursor.moveToNext();
  378.                         }//while
  379.                         db.close();
  380.                     }//if
  381.                 }//if can read the database
  382.             }//try
  383.             catch(Exception e){
  384.                 Log.e(
  385.                     this.getClass().getName(), //log's category
  386.                     e.toString() //message logged (will be visible in LogCat)
  387.                 );
  388.             }//catch
  389.         }//if got a non empty query
  390.  
  391.         return aRet;
  392.     }//selectAll
  393. }//ContactDB
  394.  
  395. //**
  396.  
  397. package com.joythis.android.myphonecaller;
  398.  
  399. import androidx.annotation.NonNull;
  400. import androidx.appcompat.app.AppCompatActivity;
  401.  
  402. import android.content.Context;
  403. import android.os.Bundle;
  404. import android.view.Menu;
  405. import android.view.MenuInflater;
  406. import android.view.MenuItem;
  407. import android.view.View;
  408. import android.widget.AdapterView;
  409. import android.widget.ArrayAdapter;
  410. import android.widget.Button;
  411. import android.widget.EditText;
  412. import android.widget.ListView;
  413.  
  414. import java.util.ArrayList;
  415.  
  416. public class MainActivity extends AppCompatActivity {
  417.  
  418.     //data members
  419.     Context mContext;
  420.     ContactDB mDB;
  421.     AmUtil mUtil;
  422.     ArrayList<Contact> mAlContacts; //runtime representation of the contacts managed by the app
  423.  
  424.     EditText mEtName, mEtNumber;
  425.     Button mBtnInsertContact;
  426.     ListView mLvContacts;
  427.     ArrayAdapter<Contact> mAd;
  428.  
  429.     ListView.OnItemLongClickListener mLvLongClickHandler =
  430.     new ListView.OnItemLongClickListener() {
  431.         @Override
  432.         public boolean onItemLongClick
  433.         (AdapterView<?> parent, //the ListView
  434.          View view, //the particular item with which the user is interacting with
  435.          int position, //the index of the item in the corresponding data
  436.          long id
  437.         )
  438.         {
  439.             Contact c = mAlContacts.get(position);
  440.             String strNumber = c.getNumber();
  441.  
  442.             mUtil.fb("Will phone to "+strNumber);
  443.             mUtil.phoneTo(strNumber);
  444.  
  445.             //return false; //the chain of events will keep going on
  446.             return true; //the event was fully consumed
  447.         }//onItemLongClick
  448.     };//mLvLongClickHandler
  449.  
  450.     Button.OnClickListener mButtonClickHandler =
  451.         new Button.OnClickListener() {
  452.         @Override
  453.         public void onClick(View v) {
  454.             switch(v.getId()){
  455.                 case R.id.idBtnInsertContact:
  456.                     actionInsertContact();
  457.                     break;
  458.             }//switch
  459.         }//onClick
  460.     };//mButtonClickHandler
  461.  
  462.     void actionInsertContact(){
  463.         String strName = mEtName.getText().toString().trim();
  464.         String strNumber = mEtNumber.getText().toString().trim();
  465.  
  466.         boolean bCheck = strName.length()>0 && strNumber.length()>0;
  467.         if (bCheck){
  468.             Contact c = new Contact(strName, strNumber);
  469.             long iWhereInserted = mDB.insertContact(c);
  470.             //mAlContacts.add(c);
  471.             ArrayList<Contact> alAfterInsert = mDB.selectAllContactsByInsertDateDESC();
  472.             syncContactsDataWithTheirPresentation(alAfterInsert);
  473.         }//
  474.         else{
  475.             mUtil.fb("Name and Number can NOT be empty!");
  476.         }
  477.     }//actionInsertContact
  478.  
  479.     @Override
  480.     protected void onCreate(Bundle savedInstanceState) {
  481.         super.onCreate(savedInstanceState);
  482.         setContentView(R.layout.insert_contact_rl);
  483.  
  484.         init();
  485.     }//onCreate
  486.  
  487.     void init(){
  488.         mContext = this;
  489.         mDB = new ContactDB(this);
  490.         mUtil = new AmUtil(this);
  491.         mAlContacts = new ArrayList<>();
  492.  
  493.         mEtName = findViewById(R.id.idEtName);
  494.         mEtNumber = findViewById(R.id.idEtNumber);
  495.         mBtnInsertContact = findViewById(R.id.idBtnInsertContact);
  496.         mBtnInsertContact.setOnClickListener(
  497.             mButtonClickHandler
  498.         );
  499.  
  500.         mLvContacts = findViewById(R.id.idLvContacts);
  501.  
  502.         mAd = new ArrayAdapter<>(
  503.             mContext,
  504.             android.R.layout.simple_list_item_1, //the object for viewing each list item
  505.             mAlContacts //the data (at a specific memory address)
  506.         );
  507.  
  508.         mLvContacts.setAdapter(mAd);
  509.         mLvContacts.setOnItemLongClickListener(mLvLongClickHandler);
  510.  
  511.         //TODO:
  512.         /*
  513.         layout
  514.         op layout
  515.          */
  516.  
  517.         ArrayList<Contact> alSortedByDateDesc = mDB.selectAllContactsByInsertDateDESC();
  518.         syncContactsDataWithTheirPresentation(alSortedByDateDesc);
  519.     }//init
  520.  
  521.     /*
  522.     this method assigns a "menu resource file" to the
  523.     activity's action bar.
  524.      */
  525.     @Override
  526.     public boolean onCreateOptionsMenu(Menu pMenu) {
  527.         MenuInflater minf = this.getMenuInflater();
  528.         if (minf!=null){
  529.             minf.inflate(
  530.                 R.menu.sorting_options_menu,//id the XML for the menu
  531.                 pMenu //Java ref to assign to the menu
  532.             );
  533.         }//if
  534.  
  535.         return super.onCreateOptionsMenu(pMenu);
  536.     }//onCreateOptionsMenu
  537.  
  538.     /*
  539.     here we code what should happen upon the selection of
  540.     any of the menu options
  541.      */
  542.     @Override
  543.     public boolean onOptionsItemSelected(@NonNull MenuItem pMenuItem) {
  544.         switch(pMenuItem.getItemId()){
  545.             case R.id.idMenuItemSortNameAsc:
  546.                 actionSortNameAsc();
  547.                 break;
  548.             case R.id.idMenuItemSortNameDesc:
  549.                 actionSortNameDesc();
  550.                 break;
  551.             case R.id.idMenuItemSortNumberAsc:
  552.                 actionSortNumberAsc();
  553.                 break;
  554.             case R.id.idMenuItemSortNumberDesc:
  555.                 actionSortNumberDesc();
  556.                 break;
  557.             case R.id.idMenuItemSortInsertDateAsc:
  558.                 actionSortInsertDateAsc();
  559.                 break;
  560.             case R.id.idMenuItemSortInsertDateDesc:
  561.                 actionSortInsertDateDesc();
  562.                 break;
  563.         }//switch
  564.         return super.onOptionsItemSelected(pMenuItem);
  565.     }
  566.  
  567.     void actionSortNameAsc(){
  568.         ArrayList<Contact> alAfterUserChoice = mDB.selectAllContactsByNameASC();
  569.         syncContactsDataWithTheirPresentation(alAfterUserChoice);
  570.     }
  571.  
  572.     void actionSortNameDesc(){
  573.         ArrayList<Contact> alAfterUserChoice = mDB.selectAllContactsByNameDESC();
  574.         syncContactsDataWithTheirPresentation(alAfterUserChoice);
  575.     }
  576.  
  577.     void actionSortNumberAsc(){
  578.         ArrayList<Contact> alAfterUserChoice = mDB.selectAllContactsByNumberASC();
  579.         syncContactsDataWithTheirPresentation(alAfterUserChoice);
  580.     }
  581.  
  582.     void actionSortNumberDesc(){
  583.         ArrayList<Contact> alAfterUserChoice = mDB.selectAllContactsByNumberDESC();
  584.         syncContactsDataWithTheirPresentation(alAfterUserChoice);
  585.     }
  586.  
  587.     void actionSortInsertDateAsc(){
  588.         ArrayList<Contact> alAfterUserChoice = mDB.selectAllContactsByInsertDateASC();
  589.         syncContactsDataWithTheirPresentation(alAfterUserChoice);
  590.     }
  591.  
  592.     void actionSortInsertDateDesc(){
  593.         ArrayList<Contact> alAfterUserChoice = mDB.selectAllContactsByInsertDateDESC();
  594.         syncContactsDataWithTheirPresentation(alAfterUserChoice);
  595.     }
  596.  
  597.     void syncContactsDataWithTheirPresentation(
  598.         ArrayList<Contact> pAlContacts
  599.     ){
  600.         //would be wrong!
  601.         //mAlContacts = pAlContacts; //would change the memory address!
  602.  
  603.         if (pAlContacts!=null && pAlContacts.size()>0){
  604.             mAlContacts.clear(); //clears the data, but keeps the original memory address to which the Adapter was bound
  605.             for (Contact c: pAlContacts){
  606.                 mAlContacts.add(c);
  607.             }//for
  608.         }//if
  609.  
  610.         mAd.notifyDataSetChanged();
  611.     }//syncContactsDataWithTheirPresentation
  612. }//MainActivity
  613.  
  614.  
Advertisement
Add Comment
Please, Sign In to add comment