0

so I've created an app which sets an alarm 25 mins before your departure time, based on the estimated time taken to travel from your place of departure to your destination.

I am able to build the app, but the app keeps crashing whenever I press the search button. I am guessing it has something to do with the integration of the placeautocomplete fragment, but not sure what about it.

Main Activity

    package com.example.mobileassignment2.buildingblocks;

import android.app.AlarmManager;
import android.app.DialogFragment;
import android.app.PendingIntent;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.places.Place;
import com.google.android.gms.location.places.ui.PlaceAutocompleteFragment;
import com.google.android.gms.location.places.ui.PlaceSelectionListener;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.Calendar;

public class MainActivity extends AppCompatActivity implements TimePickerDialog .OnTimeSetListener{

    String DistanceResult;
    String DurationResult;

    String LeaveByHour;
    String LeaveByMin;

    String AlarmTimeHour;
    String AlarmTimeMin;

    int ArriveHour;
    int ArriveMin;

    int AlarmHour;
    int AlarmMin;

    Calendar alarmCalendar;


    @Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {

        TextView textViewArriveByTime = (TextView)findViewById(R.id.textViewArriveByTime);
        textViewArriveByTime.setText("Hour: "+ hourOfDay +"\n"+ "Minute: "+minute);

        ArriveHour = hourOfDay;
        ArriveMin = minute;
    }

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

        Button button = (Button) findViewById(R.id.ArriveByBtn);
        button.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v){
                DialogFragment timePicker = new TimePickerFragment();
                timePicker.show(getFragmentManager(), "time picker");

            }

        });


Reset();
    }



    public void Reset(){
        DistanceResult = "";
        DurationResult = "";
        TextView Distance_Output = (TextView) findViewById(R.id.DistanceResult);
        TextView Duration_Output = (TextView) findViewById(R.id.DurationResult);
        Distance_Output.setText("Distance: " + DistanceResult);
        Duration_Output.setText("Duration: " + DurationResult);


        LeaveByMin = "";
        AlarmTimeMin = "";
        TextView LeaveBy_Calculated = (TextView) findViewById(R.id.LeaveBy);
        LeaveBy_Calculated.setText("Leave By: " + LeaveByMin);
        TextView AlarmTime_Calculated = (TextView) findViewById(R.id.AlarmTime);
        AlarmTime_Calculated.setText("Alarm Time: " + AlarmTimeMin);

        TextView textViewArriveByTime = (TextView)findViewById(R.id.textViewArriveByTime);
        textViewArriveByTime.setText("Hour: "+"\n"+ "Minute: ");


    }

    private static final String TAG = "MainActivity";



    public void SearchDistanceCommand(View view) {


        PlaceAutocompleteFragment Start_Location = (PlaceAutocompleteFragment)
                getFragmentManager().findFragmentById(R.id.StartLocation);

        Start_Location.setOnPlaceSelectedListener(new PlaceSelectionListener() {
            @Override
            public void onPlaceSelected(Place place) {
                // TODO: Get info about the selected place.
                Log.i(TAG, "Place: " + place.getName());
            }

            @Override
            public void onError(Status status) {
                // TODO: Handle the error.
                Log.i(TAG, "An error occurred: " + status);
            }
        });



        PlaceAutocompleteFragment Goal_Location = (PlaceAutocompleteFragment)
                getFragmentManager().findFragmentById(R.id.GoalLocation);

        Goal_Location.setOnPlaceSelectedListener(new PlaceSelectionListener() {
            @Override
            public void onPlaceSelected(Place place) {
                // TODO: Get info about the selected place.
                Log.i(TAG, "Place: " + place.getName());
            }

            @Override
            public void onError(Status status) {
                // TODO: Handle the error.
                Log.i(TAG, "An error occurred: " + status);
            }
        });


        Reset();

        if(Start_Location.toString().isEmpty()|| Goal_Location.toString().isEmpty()){
            Toast MissingTextErrorHandle = Toast.makeText(getApplicationContext(), "You need to input data into both fields!", Toast.LENGTH_SHORT);
            MissingTextErrorHandle.show();
        }
        else
        {
            new AsyncTaskParseJson().execute();
        }
    }

    public class AsyncTaskParseJson extends AsyncTask<String, String, String> {

        EditText Start_Location = (EditText) findViewById(R.id.StartLocation);
        EditText Goal_Location = (EditText) findViewById(R.id.GoalLocation);
        //To convert to UTC, how to use time picker
      //  EditText Arrive_By = (EditText) findViewById(R.id.ArriveBy);

        String FormattedStartLocation = Start_Location.getText().toString().replaceAll(" ", "+");
        String FormattedGoalLocation = Goal_Location.getText().toString().replaceAll(" ", "+");

        String yourServiceUrl = "https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins=" + FormattedStartLocation + "&destinations=" + FormattedGoalLocation
               /* + "&arrival_time=" + Arrive_By*/
                + "&key=___MY___SECRET___KEY___";

        @Override
        protected void onPreExecute() {
            ProgressBar spinner;
            spinner = (ProgressBar) findViewById(R.id.progressBar1);
            spinner.setVisibility(View.VISIBLE);
        }

        @Override
        protected String doInBackground(String... arg0) {
            try {
                httpConnect jParser = new httpConnect();
                String json = jParser.getJSONFromUrl(yourServiceUrl);
                JSONObject object = new JSONObject(json);

                //contains ALL routes
                JSONArray array = object.getJSONArray("rows");
                // Get the first route
                JSONObject route = array.getJSONObject(0);
                // Take all elements
                JSONArray elements = route.getJSONArray("elements");
                //Take First Element
                JSONObject element = elements.getJSONObject(0);

                // Get Duration
                JSONObject durationObject = element.getJSONObject("duration");
                String duration = durationObject.getString("text");
                DurationResult = duration;

                // Get Distance
                JSONObject distanceObject = element.getJSONObject("distance");
                String distance = distanceObject.getString("text");
                DistanceResult = distance;

               //Get Leave By Time (ATTENTION!!: Need to edit for when duration > 1hr)

              String sDMin = DurationResult;

              //Nic: Remove Characters, Convert duration str to int, !!Assume duration is <1 Hr
              sDMin = sDMin.replaceAll( " mins", "" );
              int dMin = Integer.parseInt(sDMin);

                int remMin = dMin % 60;
                int remHour = dMin / 60;

                int leaveHour = ArriveHour - remHour;
                if (leaveHour < 0){
                    leaveHour = 23;
                }
                int leaveMin = ArriveMin - remMin -5;
                if (leaveMin < 0){
                    leaveHour -= 1;
                    leaveMin += 60;
                    if (leaveHour < 0){
                        leaveHour = 23;
                    }

                }

                //Convert int to str for printing
                String sLeaveHour = Integer.toString(leaveHour);
                String sLeaveMin = Integer.toString(leaveMin);
                LeaveByHour = sLeaveHour;
                LeaveByMin = sLeaveMin;


                //Get Alarm Time (int value), alarmManager later

                //String sATMin = DurationResult;

                //Nic: Remove Characters, Convert duration str to int, !!Assume duration is <1 Hr
                //sATMin = sATMin.replaceAll( " mins", "" );
                //int atMin = Integer.parseInt(sATMin);

                /*int remAlarmMin = (atMin % 60) - 30;
                int remAlarmHour = atMin / 60;


                int alarmHour = ArriveHour - remAlarmHour;
                int alarmMin = ArriveMin - remAlarmMin;
                if (alarmMin < 0){
                    alarmHour -= 1;
                    alarmMin += 60;*/

                int alarmHour = leaveHour;
                if(alarmHour < 0){
                    alarmHour = 23;
                }
                int alarmMin = leaveMin - 30;
                if (alarmMin < 0){
                    alarmHour -= 1;
                    alarmMin += 60;
                    if(alarmHour < 0){
                        alarmHour = 23;
                    }
                }

                //Set Global Variable to set calendar to set Alarm time
                AlarmHour = alarmHour;
                AlarmMin = alarmMin;



                //Convert int to str for printing
                String sAlarmHour = Integer.toString(alarmHour);
                String sAlarmMin = Integer.toString(alarmMin);
                AlarmTimeHour = sAlarmHour;
                AlarmTimeMin = sAlarmMin;



                Calendar calendar = Calendar.getInstance();

                calendar.set(
                        calendar.get(Calendar.YEAR),
                        calendar.get(Calendar.MONTH),
                        calendar.get(Calendar.DAY_OF_MONTH),
                        AlarmHour,
                        AlarmMin,
                        0);

                alarmCalendar = calendar;

                setAlarm(alarmCalendar.getTimeInMillis());

            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String strFromDoInBg) {

            if(DistanceResult == null || DurationResult == null){
                Toast ResultErrorHandle = Toast.makeText(getApplicationContext(), "We could not find any results! Sorry!", Toast.LENGTH_SHORT);
                ResultErrorHandle.show();
            }

            ProgressBar spinner;
            spinner = (ProgressBar) findViewById(R.id.progressBar1);
            spinner.setVisibility(View.INVISIBLE);

            TextView Distance_Output = (TextView) findViewById(R.id.DistanceResult);
            Distance_Output.setText("Distance: " + DistanceResult);

            TextView Duration_Output = (TextView) findViewById(R.id.DurationResult);
            Duration_Output.setText("Duration: " + DurationResult);

            TextView LeaveBy_Calculated = (TextView) findViewById(R.id.LeaveBy);
            LeaveBy_Calculated.setText("Leave By| Hour: " + LeaveByHour + "  Min: " + LeaveByMin);

           TextView AlarmTime_Calculated = (TextView) findViewById(R.id.AlarmTime);
            AlarmTime_Calculated.setText("Alarm Time| Hour " + AlarmTimeHour + "  Min: " + AlarmTimeMin);
        }
    }

    public void CancelAlarmCommand(){
        cancelAlarm();
    }

    public void setAlarm(long timeInMillis) {

        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);


        Intent intent = new Intent(this, AlarmReceiver.class);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,intent,0);

        AlarmManager.AlarmClockInfo ac= new AlarmManager.AlarmClockInfo(timeInMillis, pendingIntent.getBroadcast(this,0,intent,0));

        alarmManager.setAlarmClock(ac,pendingIntent);

        Toast.makeText(this, "Alarm set!", Toast.LENGTH_SHORT).show();
    }

    private void cancelAlarm(){

        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);


        Intent intent = new Intent(this, AlarmReceiver.class);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,intent,0);

        alarmManager.cancel(pendingIntent);

        }
    }

Gradle App

     apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion '27.0.3'
    defaultConfig {
        applicationId "com.example.mobileassignment2.buildingblocks"
        minSdkVersion 21
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    //noinspection GradleCompatible
    implementation 'com.android.support:appcompat-v7:25.3.1'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'

    implementation 'com.google.android.gms:play-services-places:15.0.1'
    implementation 'com.google.android.gms:play-services-location:15.0.1'

}

Android Manifest

<?xml version="1.0" encoding="utf-8"?>

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />



<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

    </activity>
    <receiver
        android:name=".AlarmReceiver"
        android:enabled="true"
        android:exported="true" />
    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="AIzaSyC0UU_6yNvnroXuHBWPd2_SPfBP9Y29bp4"/>

</application>

logcat

09-05 00:04:22.519 1530-9975/? I/AudioFlinger: AudioFlinger's thread 0xe57037c0 tid=9975 ready to run 09-05 00:04:22.546 1530-1603/? E/AudioFlinger: not enough memory for AudioTrack size=131296 09-05 00:04:22.548 1530-1603/? E/AudioFlinger: createRecordTrack_l() initCheck failed -12; no control block? 09-05 00:04:22.554 2336-9720/com.google.android.googlequicksearchbox:search E/AudioRecord: AudioFlinger could not create record track, status: -12 09-05 00:04:22.575 2336-9720/com.google.android.googlequicksearchbox:search E/AudioRecord-JNI: Error creating AudioRecord instance: initialization check failed with status -12. 09-05 00:04:22.578 2336-9720/com.google.android.googlequicksearchbox:search E/android.media.AudioRecord: Error code -20 when initializing native AudioRecord object.

Nicole
  • 1
  • 1
  • 1
    post the logcat – Rubick Sep 04 '18 at 23:48
  • 1
    `app keeps crashing` those _crashes_ produce wonderful log entries which point you right back to the line if your code that caused the abort. Check your [`logcat`](https://developer.android.com/studio/debug/am-logcat), then [edit] your question to post this wonderful log message, if you can not interpret it yourself. Currently voting to close for lack of details. – Matt Clark Sep 04 '18 at 23:50
  • Please see [Unfortunately MyApp has stopped. How can I solve this?](https://stackoverflow.com/questions/23353173/unfortunately-myapp-has-stopped-how-can-i-solve-this). – Gino Mempin Sep 04 '18 at 23:52
  • Hi again, the attached LogCat seems to be from another app running. Please cause your app to crash, then again look through logcat, There will be many lines. Maybe filter by your apps name. – Matt Clark Sep 05 '18 at 00:20
  • Alright thank you!!! – Nicole Sep 05 '18 at 09:26

0 Answers0