2017-11-06 2 views
0

지오 펜스를 넘었을 때 다른 전화로 SMS를 보내는 앱을 만들려고합니다. Google 샘플 geofence에서 코드를 빌 렸습니다. 지오 펜스가 호출 될 때 어떤 메소드가 실행되는지 알고 싶었습니다. getGeofencePendingIntent 메소드에 내 코드를 삽입 해 보았습니다 (주석으로 표시된 것처럼). 그러나 지오 펜스 추가 또는 지오 펜스 제거 버튼을 클릭 할 때마다 SMS가 전송되었습니다. GeofenceTransitionsIntentService 클래스의 알림도 실행되지 않았습니다.지오 펜스가 넘어갈 때 실행되는 메소드는 무엇입니까?

GeofenceTransitionsIntentService 클래스 자체에 코드를 넣으려고했습니다. 왜냐하면 지오 펜스를 넘었을 때 코드가 실행 되더라도 코드가 존재한다고 생각했기 때문입니다. 그러나 이로 인해 알림뿐만 아니라 SMS가 실행되지 않습니다.

String phoneNum = editText2.getText().toString(); 


     if (phoneNum.length()>9 && phoneNum.length()<11) { 
      SmsManager smsManager = SmsManager.getDefault(); 
      smsManager.sendTextMessage(phoneNum, null, "This is part of an SMS text message!", null, null); 
     } 

     else 
     { 
      // display message if text fields are empty 
      Toast.makeText(getBaseContext(),"Please add a correct phone number.",Toast.LENGTH_SHORT).show(); 
     } 

이는 SetGeofence에 내 코드 (주요 활동) 클래스 :

다음은 SMS를 보내는 코드이다

package com.indianstudentroom.senioralert; 

import android.Manifest; 
import android.app.PendingIntent; 
import android.content.Intent; 
import android.content.pm.PackageManager; 
import android.net.Uri; 
import android.os.Bundle; 
import android.preference.PreferenceManager; 
import android.provider.Settings; 
import android.support.annotation.NonNull; 
import android.support.design.widget.Snackbar; 
import android.support.v4.app.ActivityCompat; 
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.Toast; 

import com.google.android.gms.location.Geofence; 
import com.google.android.gms.location.GeofencingClient; 
import com.google.android.gms.location.GeofencingRequest; 
import com.google.android.gms.location.LocationServices; 
import com.google.android.gms.maps.model.LatLng; 
import com.google.android.gms.tasks.OnCompleteListener; 
import com.google.android.gms.tasks.Task; 

import java.util.ArrayList; 
import java.util.Map; 


public class SetGeofence extends AppCompatActivity implements OnCompleteListener<Void> { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_set_geofence); 


     // Get the UI widgets. 
     mAddGeofencesButton = (Button) findViewById(R.id.add_geofences_button); 
     mRemoveGeofencesButton = (Button) findViewById(R.id.remove_geofences_button); 
     openMonitoringButton = (Button) findViewById(R.id.button); 

     editText2 = (EditText) findViewById(R.id.edit_text); 


     // Empty list for storing geofences. 
     mGeofenceList = new ArrayList<>(); 

     // Initially set the PendingIntent used in addGeofences() and removeGeofences() to null. 
     mGeofencePendingIntent = null; 

     setButtonsEnabledState(); 

     // Get the geofences used. Geofence data is hard coded in this sample. 
     populateGeofenceList(); 

     mGeofencingClient = LocationServices.getGeofencingClient(this); 

    } 


    private static final String TAG = MainActivity.class.getSimpleName(); 

    private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34; 

    /** 
    * Tracks whether the user requested to add or remove geofences, or to do neither. 
    */ 
    private enum PendingGeofenceTask { 
     ADD, REMOVE, NONE 
    } 

    /** 
    * Provides access to the Geofencing API. 
    */ 
    private GeofencingClient mGeofencingClient; 

    /** 
    * The list of geofences used in this sample. 
    */ 
    private ArrayList<Geofence> mGeofenceList; 

    /** 
    * Used when requesting to add or remove geofences. 
    */ 
    private PendingIntent mGeofencePendingIntent; 

    // Buttons for kicking off the process of adding or removing geofences. 
    private Button mAddGeofencesButton; 
    private Button mRemoveGeofencesButton; 
    public EditText editText2; 
    private Button openMonitoringButton; 

    private PendingGeofenceTask mPendingGeofenceTask = PendingGeofenceTask.NONE; 


    @Override 
    public void onStart() { 
     super.onStart(); 

     if (!checkPermissions()) { 
      requestPermissions(); 
     } else { 
      performPendingGeofenceTask(); 
     } 
    } 


    /** 
    * Builds and returns a GeofencingRequest. Specifies the list of geofences to be monitored. 
    * Also specifies how the geofence notifications are initially triggered. 
    */ 
    private GeofencingRequest getGeofencingRequest() { 
     GeofencingRequest.Builder builder = new GeofencingRequest.Builder(); 

     // The INITIAL_TRIGGER_ENTER flag indicates that geofencing service should trigger a 
     // GEOFENCE_TRANSITION_ENTER notification when the geofence is added and if the device 
     // is already inside that geofence. 
     builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER); 

     // Add the geofences to be monitored by geofencing service. 
     builder.addGeofences(mGeofenceList); 

     // Return a GeofencingRequest. 
     return builder.build(); 
    } 


    /** 
    * Adds geofences, which sets alerts to be notified when the device enters or exits one of the 
    * specified geofences. Handles the success or failure results returned by addGeofences(). 
    */ 
    public void addGeofencesButtonHandler(View view) { 
     if (!checkPermissions()) { 
      mPendingGeofenceTask = PendingGeofenceTask.ADD; 
      requestPermissions(); 
      return; 
     } 

     addGeofences(); 

    } 

    /** 
    * Adds geofences. This method should be called after the user has granted the location 
    * permission. 
    */ 
    @SuppressWarnings("MissingPermission") 
    private void addGeofences() { 
     if (!checkPermissions()) { 
      showSnackbar(getString(R.string.insufficient_permissions)); 
      return; 
     } 

     mGeofencingClient.addGeofences(getGeofencingRequest(), getGeofencePendingIntent()) 
       .addOnCompleteListener(this); 
    } 

    /** 
    * Removes geofences, which stops further notifications when the device enters or exits 
    * previously registered geofences. 
    */ 
    public void removeGeofencesButtonHandler(View view) { 
     if (!checkPermissions()) { 
      mPendingGeofenceTask = PendingGeofenceTask.REMOVE; 
      requestPermissions(); 
      return; 
     } 
     removeGeofences(); 
    } 

    /** 
    * Removes geofences. This method should be called after the user has granted the location 
    * permission. 
    */ 
    @SuppressWarnings("MissingPermission") 
    private void removeGeofences() { 
     if (!checkPermissions()) { 
      showSnackbar(getString(R.string.insufficient_permissions)); 
      return; 
     } 

     mGeofencingClient.removeGeofences(getGeofencePendingIntent()).addOnCompleteListener(this); 
    } 


    public void openMonitoring() { 
     Intent intent = new Intent(SetGeofence.this, Monitoring.class); 
     startActivity(intent); 
    } 

    /** 
    * Runs when the result of calling {@link #addGeofences()} and/or {@link #removeGeofences()} 
    * is available. 
    * 
    * @param task the resulting Task, containing either a result or error. 
    */ 
    @Override 
    public void onComplete(@NonNull Task<Void> task) { 
     mPendingGeofenceTask = PendingGeofenceTask.NONE; 
     if (task.isSuccessful()) { 
      updateGeofencesAdded(!getGeofencesAdded()); 
      setButtonsEnabledState(); 


      int messageId = getGeofencesAdded() ? R.string.geofences_added : 
        R.string.geofences_removed; 
      Toast.makeText(this, getString(messageId), Toast.LENGTH_SHORT).show(); 

      if (getString(messageId).equals(R.string.geofences_added)) { 
       openMonitoring(); 
      } 


     } else { 
      // Get the status code for the error and log it using a user-friendly message. 
      String errorMessage = GeofenceErrorMessages.getErrorString(this, task.getException()); 
      Log.w(TAG, errorMessage); 
     } 
    } 


    /** 
    * Gets a PendingIntent to send with the request to add or remove Geofences. Location Services 
    * issues the Intent inside this PendingIntent whenever a geofence transition occurs for the 
    * current list of geofences. 
    * 
    * @return A PendingIntent for the IntentService that handles geofence transitions. 
    */ 


    private PendingIntent getGeofencePendingIntent() { 
     // Reuse the PendingIntent if we already have it. 
     if (mGeofencePendingIntent != null) { 
      return mGeofencePendingIntent; 
     } 

      /* String phoneNum = editText2.getText().toString(); 


      if (phoneNum.length()>9 && phoneNum.length()<11) { 
       SmsManager smsManager = SmsManager.getDefault(); 
       smsManager.sendTextMessage(phoneNum, null, "The person under your care has left the geofence! Please take the appropriate action and save them!", null, null); 
      } 

      else 
      { 
       // display message if text fields are empty 
       Toast.makeText(getBaseContext(),"Please add a correct phone number.",Toast.LENGTH_SHORT).show(); 
      } 
*/ 
     Intent intent = new Intent(this, GeofenceTransitionsIntentService.class); 
     // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling 
     // addGeofences() and removeGeofences(). 
     return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
    } 


    /** 
    * This sample hard codes geofence data. A real app might dynamically create geofences based on 
    * the user's location. 
    */ 
    private void populateGeofenceList() { 
     for (Map.Entry<String, LatLng> entry : Constants.BAY_AREA_LANDMARKS.entrySet()) { 

      mGeofenceList.add(new Geofence.Builder() 
        // Set the request ID of the geofence. This is a string to identify this 
        // geofence. 
        .setRequestId(entry.getKey()) 

        // Set the circular region of this geofence. 
        .setCircularRegion(
          entry.getValue().latitude, 
          entry.getValue().longitude, 
          Constants.GEOFENCE_RADIUS_IN_METERS 
        ) 

        // Set the expiration duration of the geofence. This geofence gets automatically 
        // removed after this period of time. 
        .setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS) 

        // Set the transition types of interest. Alerts are only generated for these 
        // transition. We track entry and exit transitions in this sample. 
        .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | 
          Geofence.GEOFENCE_TRANSITION_EXIT) 

        // Create the geofence. 
        .build()); 
     } 
    } 

    /** 
    * Ensures that only one button is enabled at any time. The Add Geofences button is enabled 
    * if the user hasn't yet added geofences. The Remove Geofences button is enabled if the 
    * user has added geofences. 
    */ 
    private void setButtonsEnabledState() { 
     if (getGeofencesAdded()) { 
      mAddGeofencesButton.setEnabled(false); 
      mRemoveGeofencesButton.setEnabled(true); 
      openMonitoringButton.setEnabled(true); 

     } else { 
      mAddGeofencesButton.setEnabled(true); 
      mRemoveGeofencesButton.setEnabled(false); 
      openMonitoringButton.setEnabled(false); 
     } 
    } 

    public void openMonitoring(View view) { 

     Intent i = new Intent(SetGeofence.this, Monitoring.class); 
     startActivity(i); 

    } 

    /** 
    * Shows a {@link Snackbar} using {@code text}. 
    * 
    * @param text The Snackbar text. 
    */ 
    private void showSnackbar(final String text) { 
     View container = findViewById(android.R.id.content); 
     if (container != null) { 
      Snackbar.make(container, text, Snackbar.LENGTH_LONG).show(); 
     } 
    } 

    /** 
    * Shows a {@link Snackbar}. 
    * 
    * @param mainTextStringId The id for the string resource for the Snackbar text. 
    * @param actionStringId The text of the action item. 
    * @param listener   The listener associated with the Snackbar action. 
    */ 
    private void showSnackbar(final int mainTextStringId, final int actionStringId, 
           View.OnClickListener listener) { 
     Snackbar.make(
       findViewById(android.R.id.content), 
       getString(mainTextStringId), 
       Snackbar.LENGTH_INDEFINITE) 
       .setAction(getString(actionStringId), listener).show(); 
    } 

    /** 
    * Returns true if geofences were added, otherwise false. 
    */ 
    private boolean getGeofencesAdded() { 
     return PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
       Constants.GEOFENCES_ADDED_KEY, false); 
    } 

    /** 
    * Stores whether geofences were added ore removed in {SharedPreferences }; 
    * 
    * @param added Whether geofences were added or removed. 
    */ 
    private void updateGeofencesAdded(boolean added) { 
     PreferenceManager.getDefaultSharedPreferences(this) 
       .edit() 
       .putBoolean(Constants.GEOFENCES_ADDED_KEY, added) 
       .apply(); 
    } 

    /** 
    * Performs the geofencing task that was pending until location permission was granted. 
    */ 
    private void performPendingGeofenceTask() { 
     if (mPendingGeofenceTask == PendingGeofenceTask.ADD) { 
      addGeofences(); 
     } else if (mPendingGeofenceTask == PendingGeofenceTask.REMOVE) { 
      removeGeofences(); 
     } 
    } 

    /** 
    * Return the current state of the permissions needed. 
    */ 
    private boolean checkPermissions() { 
     int permissionState = ActivityCompat.checkSelfPermission(this, 
       Manifest.permission.ACCESS_FINE_LOCATION); 
     return permissionState == PackageManager.PERMISSION_GRANTED; 
    } 

    private void requestPermissions() { 
     boolean shouldProvideRationale = 
       ActivityCompat.shouldShowRequestPermissionRationale(this, 
         Manifest.permission.ACCESS_FINE_LOCATION); 

     // Provide an additional rationale to the user. This would happen if the user denied the 
     // request previously, but didn't check the "Don't ask again" checkbox. 
     if (shouldProvideRationale) { 
      Log.i(TAG, "Displaying permission rationale to provide additional context."); 
      showSnackbar(R.string.permission_rationale, android.R.string.ok, 
        new View.OnClickListener() { 
         @Override 
         public void onClick(View view) { 
          // Request permission 
          ActivityCompat.requestPermissions(SetGeofence.this, 
            new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 
            REQUEST_PERMISSIONS_REQUEST_CODE); 
         } 
        }); 
     } else { 
      Log.i(TAG, "Requesting permission"); 
      // Request permission. It's possible this can be auto answered if device policy 
      // sets the permission in a given state or the user denied the permission 
      // previously and checked "Never ask again". 
      ActivityCompat.requestPermissions(SetGeofence.this, 
        new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 
        REQUEST_PERMISSIONS_REQUEST_CODE); 
     } 
    } 

    /** 
    * Callback received when a permissions request has been completed. 
    */ 
    @Override 
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, 
              @NonNull int[] grantResults) { 
     Log.i(TAG, "onRequestPermissionResult"); 
     if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) { 
      if (grantResults.length <= 0) { 
       // If user interaction was interrupted, the permission request is cancelled and you 
       // receive empty arrays. 
       Log.i(TAG, "User interaction was cancelled."); 
      } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
       Log.i(TAG, "Permission granted."); 
       performPendingGeofenceTask(); 
      } else { 
       // Permission denied. 

       // Notify the user via a SnackBar that they have rejected a core permission for the 
       // app, which makes the Activity useless. In a real app, core permissions would 
       // typically be best requested during a welcome-screen flow. 

       // Additionally, it is important to remember that a permission might have been 
       // rejected without asking the user for permission (device policy or "Never ask 
       // again" prompts). Therefore, a user interface affordance is typically implemented 
       // when permissions are denied. Otherwise, your app could appear unresponsive to 
       // touches or interactions which have required permissions. 
       showSnackbar(R.string.permission_denied_explanation, R.string.settings, 
         new View.OnClickListener() { 
          @Override 
          public void onClick(View view) { 
           // Build intent that displays the App settings screen. 
           Intent intent = new Intent(); 
           intent.setAction(
             Settings.ACTION_APPLICATION_DETAILS_SETTINGS); 
           Uri uri = Uri.fromParts("package", 
             BuildConfig.APPLICATION_ID, null); 
           intent.setData(uri); 
           intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
           startActivity(intent); 
          } 
         }); 
       mPendingGeofenceTask = PendingGeofenceTask.NONE; 
      } 
     } 
    } 
} 

정말 고마워요!

+0

GeofenceTransitionsIntentService 코드를 게시 할 수 있습니까? 지오 펜스가 입력/종료 될 때 해당 클래스의 'onHandleIntent'가 실행되어야합니다. – NinjaCoder

+0

안녕하세요, 답변 해 주셔서 감사합니다. 당신이 맞았습니다, 그것은 지오 펜스가 출입 될 때 실행 된 방법이었습니다. 내 코드를 거기에 넣으면 작동합니다. – BLRBoy

+0

확인. 나는 당신이 그것을 표시하고 질문을 닫을 수 있도록 대답을 게시했다. – NinjaCoder

답변

0

onHandleIntent on GeofenceTransitionsIntentService은 지오 펜스가 입력/종료 될 때 실행되어야합니다. 해당 방법으로 코드 게시

관련 문제