com.jlcsoftware.callrecorder.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.jlcsoftware.callrecorder.MainActivity.java

Source

package com.jlcsoftware.callrecorder;

import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.design.widget.TabLayout;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.SwitchCompat;
import android.support.v7.widget.Toolbar;
import android.text.Html;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.MediaController;
import android.widget.Toast;

import com.jlcsoftware.database.CallLog;
import com.jlcsoftware.database.Database;
import com.jlcsoftware.helpers.AboutDialog;
import com.jlcsoftware.helpers.RateMeNowDialog;

import java.io.File;
import java.util.ArrayList;

/**
 * Our MAIN Activity - MAIN LAUNCHER
 *
 */

public class MainActivity extends AppCompatActivity implements RecordingFragment.OnListFragmentInteractionListener,
        MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener, MediaController.MediaPlayerControl {

    /**
     * The {@link android.support.v4.view.PagerAdapter} that will provide
     * fragments for each of the sections. We use a
     * {@link FragmentPagerAdapter} derivative, which will keep every
     * loaded fragment in memory. If this becomes too memory intensive, it
     * may be best to switch to a
     * {@link android.support.v4.app.FragmentStatePagerAdapter}.
     */
    private SectionsPagerAdapter mSectionsPagerAdapter;

    /**
     * The {@link ViewPager} that will host the section contents.
     */
    private ViewPager mViewPager;
    private Handler handler = new Handler();

    boolean isLicensed;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        checkPermissions();

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.container);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(mViewPager);

        //set up MediaPlayer
        mediaController = new MediaController(this);
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setOnPreparedListener(this);
        mediaPlayer.setOnCompletionListener(this);

        RateMeNowDialog.showRateDialog(this, 10);

    }

    @Override
    protected void onStop() {
        super.onStop();
        mediaController.hide();
        if (mediaPlayer.isPlaying())
            mediaPlayer.stop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mediaPlayer.release();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //the MediaController will hide after 3 seconds - tap the screen to make it appear again
        mediaController.show();
        return false;
    }

    Menu optionsMenu;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        optionsMenu = menu;
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);

        SwitchCompat switchCompat = (SwitchCompat) menu.findItem(R.id.onswitch).getActionView()
                .findViewById(R.id.switch1);
        switchCompat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                AppPreferences.getInstance(MainActivity.this).setRecordingEnabled(isChecked);
            }
        });
        switchCompat.setChecked(AppPreferences.getInstance(MainActivity.this).isRecordingEnabled());
        return true;
    }

    boolean doubleBackToExitPressedOnce;

    @Override
    public void onBackPressed() {
        if (doubleBackToExitPressedOnce) {
            super.onBackPressed();
            return;
        }

        // Does the user really want to exit?
        this.doubleBackToExitPressedOnce = true;
        Toast.makeText(this, getString(R.string.press_back_again), Toast.LENGTH_LONG).show();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                doubleBackToExitPressedOnce = false;
            }
        }, 2000);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            Intent intent = new Intent(this, SettingsActivity.class);
            startActivity(intent);
            return true;
        }

        if (id == R.id.action_save) {
            if (null != selectedItems && selectedItems.length > 0) {
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        for (PhoneCallRecord record : selectedItems) {
                            record.getPhoneCall().setKept(true);
                            record.getPhoneCall().save(MainActivity.this);
                        }
                        LocalBroadcastManager.getInstance(MainActivity.this)
                                .sendBroadcast(new Intent(LocalBroadcastActions.NEW_RECORDING_BROADCAST)); // Causes refresh

                    }
                };
                handler.post(runnable);
            }
            return true;
        }

        if (id == R.id.action_share) {
            if (null != selectedItems && selectedItems.length > 0) {
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        ArrayList<Uri> fileUris = new ArrayList<Uri>();
                        for (PhoneCallRecord record : selectedItems) {
                            fileUris.add(Uri.fromFile(new File(record.getPhoneCall().getPathToRecording())));
                        }
                        Intent shareIntent = new Intent();
                        shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
                        shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, fileUris);
                        shareIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.email_title));
                        shareIntent.putExtra(Intent.EXTRA_HTML_TEXT,
                                Html.fromHtml(getString(R.string.email_body_html)));
                        shareIntent.putExtra(Intent.EXTRA_TEXT, getString(R.string.email_body));
                        shareIntent.setType("audio/*");
                        startActivity(Intent.createChooser(shareIntent, getString(R.string.action_share)));
                    }
                };
                handler.post(runnable);
            }
            return true;
        }

        if (id == R.id.action_delete) {
            if (null != selectedItems && selectedItems.length > 0) {
                AlertDialog.Builder alert = new AlertDialog.Builder(this);
                alert.setTitle(R.string.delete_recording_title);
                alert.setMessage(R.string.delete_recording_subject);
                alert.setPositiveButton(R.string.dialog_yes, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                        Runnable runnable = new Runnable() {
                            @Override
                            public void run() {
                                Database callLog = Database.getInstance(MainActivity.this);
                                for (PhoneCallRecord record : selectedItems) {
                                    int id = record.getPhoneCall().getId();
                                    callLog.removeCall(id);
                                }

                                LocalBroadcastManager.getInstance(MainActivity.this).sendBroadcast(
                                        new Intent(LocalBroadcastActions.RECORDING_DELETED_BROADCAST));
                            }
                        };
                        handler.post(runnable);

                        dialog.dismiss();

                    }
                });
                alert.setNegativeButton(R.string.dialog_no, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                        dialog.dismiss();
                    }
                });

                alert.show();
            }
            return true;
        }

        if (id == R.id.action_delete_all) {

            AlertDialog.Builder alert = new AlertDialog.Builder(this);
            alert.setTitle(R.string.delete_recording_title);
            alert.setMessage(R.string.delete_all_recording_subject);
            alert.setPositiveButton(R.string.dialog_yes, new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {

                    Runnable runnable = new Runnable() {
                        @Override
                        public void run() {
                            Database.getInstance(MainActivity.this).removeAllCalls(false);
                            LocalBroadcastManager.getInstance(getApplicationContext())
                                    .sendBroadcast(new Intent(LocalBroadcastActions.RECORDING_DELETED_BROADCAST));
                        }
                    };
                    handler.post(runnable);

                    dialog.dismiss();

                }
            });
            alert.setNegativeButton(R.string.dialog_no, new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {

                    dialog.dismiss();
                }
            });

            alert.show();

            return true;
        }

        if (R.id.action_whitelist == id) {
            if (permissionReadContacts) {
                Intent intent = new Intent(this, WhitelistActivity.class);
                startActivity(intent);
            } else {
                AlertDialog.Builder alert = new AlertDialog.Builder(this);
                alert.setTitle(R.string.permission_whitelist_title);
                alert.setMessage(R.string.permission_whitelist);
            }
            return true;
        }
        if (R.id.action_about == id) {
            AboutDialog.show(this);
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        // Evoked by the {@link RecordCallService#displayNotification}
        setIntent(intent);
    }

    @Override
    protected void onResume() {
        super.onResume();
        Intent intent = getIntent();
        if (null != intent) {
            // User clicked the {@link RecordCallService#displayNotification} to listen to the recording
            long id = intent.getIntExtra("RecordingId", -1);
            if (-1 != id) {
                CallLog call = Database.getInstance(this).getCall((int) id);
                if (null != call) {
                    audioPlayer(call.getPathToRecording());
                }
                intent.putExtra("RecordingId", -1); // run only once...
            }
        }
    }

    @Override
    public void onListFragmentInteraction(PhoneCallRecord items[]) {
        optionsMenu.findItem(R.id.action_delete).setVisible(items.length > 0);
        optionsMenu.findItem(R.id.action_share).setVisible(items.length > 0);
        selectedItems = items;
        // the MediaController will hide after 3 seconds - tap the screen to make it appear again
        if (mediaController.isEnabled() && !mediaController.isShowing())
            mediaController.show();
    }

    PhoneCallRecord selectedItems[];

    @Override
    public void onItemPlay(PhoneCallRecord item) {
        audioPlayer(item.getPhoneCall().getPathToRecording());
    }

    @Override
    public boolean onListItemLongClick(View v, final PhoneCallRecord record, final PhoneCallRecord items[]) {
        selectedItems = items;
        PopupMenu popupMenu = new PopupMenu(this, v);
        popupMenu.getMenuInflater().inflate(R.menu.menu_main_popup, popupMenu.getMenu());

        popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                return onOptionsItemSelected(item);
            }
        });
        popupMenu.show();
        return false;
    }

    MediaPlayer mediaPlayer;
    MediaController mediaController;

    public void audioPlayer(String path) {

        try {
            mediaPlayer.reset();
            mediaPlayer.setDataSource(path);
            mediaPlayer.prepare();
            mediaPlayer.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Media Player stuff
     **/

    @Override
    public void start() {
        mediaPlayer.start();
    }

    @Override
    public void pause() {
        mediaPlayer.pause();
    }

    @Override
    public int getDuration() {
        return mediaPlayer.getDuration();
    }

    @Override
    public int getCurrentPosition() {
        return mediaPlayer.getCurrentPosition();
    }

    @Override
    public void seekTo(int pos) {
        mediaPlayer.seekTo(pos);
    }

    @Override
    public boolean isPlaying() {
        return mediaPlayer.isPlaying();
    }

    @Override
    public int getBufferPercentage() {
        return 0;
    }

    @Override
    public boolean canPause() {
        return true;
    }

    @Override
    public boolean canSeekBackward() {
        return true;
    }

    @Override
    public boolean canSeekForward() {
        return true;
    }

    @Override
    public int getAudioSessionId() {
        return 0;
    }

    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {
        mediaController.setMediaPlayer(this);
        mediaController.setAnchorView(this.findViewById(R.id.list));

        handler.post(new Runnable() {
            public void run() {
                mediaController.setEnabled(true);
                mediaController.show(5000);
            }
        });
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        mp.reset();
        mediaController.hide();
        mediaController.setEnabled(false);
    }

    boolean permissionReadContacts;

    public void checkPermissions() {
        permissionReadContacts = ActivityCompat.checkSelfPermission(this,
                Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED;

        if (!permissionReadContacts)
            if (ActivityCompat.checkSelfPermission(this,
                    Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {

                // Should we show an explanation?
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_CONTACTS)) {

                    // Show an expanation to the user *asynchronously* -- don't block
                    // this thread waiting for the user's response! After the user
                    // sees the explanation, try again to request the permission.
                    new android.app.AlertDialog.Builder(this).setCancelable(true)
                            .setMessage(R.string.str_access_permissions)
                            .setPositiveButton(R.string.dialog_ok, new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    ActivityCompat.requestPermissions(MainActivity.this,
                                            new String[] { Manifest.permission.READ_CONTACTS }, 0x01);
                                }
                            }).show();

                } else {

                    // No explanation needed, we can request the permission.

                    ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.READ_CONTACTS },
                            0x01);

                }
            }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
        case 0x01: { // validateRequestPermissionsRequestCode in FragmentActivity requires requestCode to be of 8 bits, meaning the range is from 0 to 255.
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0) { // we only asked for one permission
                permissionReadContacts = grantResults[0] == PackageManager.PERMISSION_GRANTED;
            }
        }
        }
    }

    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            // getItem is called to instantiate the fragment for the given page.
            // Return a PlaceholderFragment (defined as a static inner class below).
            if (position == 1)
                return RecordingFragment.newInstance(1, RecordingFragment.SORT_TYPE.INCOMING);
            else if (position == 2)
                return RecordingFragment.newInstance(1, RecordingFragment.SORT_TYPE.OUTGOING);
            else
                return RecordingFragment.newInstance(1, RecordingFragment.SORT_TYPE.ALL);
        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 3;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            switch (position) {
            case 0:
                return getString(R.string.all);
            case 1:
                return getString(R.string.incoming);
            case 2:
                return getString(R.string.outgoing);
            }
            return null;
        }
    }
}