লোকেশন সার্ভিস গুগল প্লে সার্ভিস APK’র একটি অংশ। যেহেতু ইউজারের ডিভাইসের অবস্থা প্রত্যাশা অনুযায়ী হওয়া কঠিন, আপনার সবসময় চেক করা উচিত যে লোকেশন সার্ভিসের সাথে সংযুক্ত হওয়ার চেষ্টা করার পূর্বে APK ইনস্টল হয়েছে। APK ইনস্টল হয়েছে কিনা তা পরীক্ষা করতে GooglePlayServicesUtil.isGooglePlayServicesAvailable() কল করুন যা রেফারেন্স ডকুমেন্টেশনের মধ্যে লিস্ট করা ইন্টিজার রেজাল্ট কোডের একটি ফেরত দেয়। আপনি যদি একটি এররের সম্মুখিন হোন, স্থানীয় ডায়লগ ফিরে পেতে GooglePlayServicesUtil.getErrorDialog() কল করুন, যে ডায়লগ ইউজারকে সঠিক কার্যক্রম গ্রহণ করতে অনুপ্রাণিত করে, তারপর একটি DialogFragment এর মধ্যে ডায়লগটি প্রদর্র্শণ করে। ডায়লগটি ইউজারকে সমস্যাটি সঠিক করতে দিতে পারে, যেই ক্ষেত্রে গুগল প্লে সার্ভিস আপনার একটিভিটিতে একটি রেজাল্ট ব্যাক পাঠাতে পারে। এই রেজাল্ট পরিচালনা করতে পদ্ধতি onActivityResult() ওভাররাইড করুন।
নোট: আপনার অ্যাপকে প্লাটফর্ম সংস্করণ ১.৬ এবং তৎপরবর্তী সংস্করনের সাথে সামঞ্জস্যপূর্ন করতে, একটিভিটি যা DialogFragment প্রদর্শন করে তাকে Activity এর পরিবর্তে অবশ্যই FragmentActivity কে সাবক্লাস করতে হবে। FragmentActivity ব্যবহার করা আপনাকে DialogFragment প্রদর্শন করতে getSupportFragmentManager() কল করতে দেয়।
যেহেতু আপনার কোডে একাধিক স্থানে সাধাারণত গুগল প্লে সার্ভিসের জন্য আপনাকে চেক করতে হয়, একটি পদ্ধতি নির্ধারণ করুন যা চেক কে আবদ্ধ করে, তারপর প্রতিটা কানেকশন প্রচেষ্টার পুর্বে পদ্ধতিটি কল করুন। নিচের কোড চিত্রটি গুগল প্লে সার্ভিস চেক করার জন্য প্রয়োজনীয় সকল
public class MainActivity extends FragmentActivity {
...
// Global constants
/*
* Define a request code to send to Google Play services
* This code is returned in Activity.onActivityResult
*/
private final static int
CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
...
// Define a DialogFragment that displays the error dialog
public static class ErrorDialogFragment extends DialogFragment {
// Global field to contain the error dialog
private Dialog mDialog;
// Default constructor. Sets the dialog field to null
public ErrorDialogFragment() {
super();
mDialog = null;
}
// Set the dialog to display
public void setDialog(Dialog dialog) {
mDialog = dialog;
}
// Return a Dialog to the DialogFragment.
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return mDialog;
}
}
...
/*
* Handle results returned to the FragmentActivity
* by Google Play services
*/
@Override
protected void onActivityResult(
int requestCode, int resultCode, Intent data) {
// Decide what to do based on the original request code
switch (requestCode) {
...
case CONNECTION_FAILURE_RESOLUTION_REQUEST :
/*
* If the result code is Activity.RESULT_OK, try
* to connect again
*/
switch (resultCode) {
case Activity.RESULT_OK :
/*
* Try the request again
*/
...
break;
}
...
}
...
}
...
private boolean servicesConnected() {
// Check that Google Play services is available
int resultCode =
GooglePlayServicesUtil.
isGooglePlayServicesAvailable(this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
// In debug mode, log the status
Log.d("Activity Recognition",
"Google Play services is available.");
// Continue
return true;
// Google Play services was not available for some reason
} else {
// Get the error dialog from Google Play services
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
resultCode,
this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
// If Google Play services can provide an error dialog
if (errorDialog != null) {
// Create a new DialogFragment for the error dialog
ErrorDialogFragment errorFragment =
new ErrorDialogFragment();
// Set the dialog in the DialogFragment
errorFragment.setDialog(errorDialog);
// Show the error dialog in the DialogFragment
errorFragment.show(
getSupportFragmentManager(),
"Activity Recognition");
}
return false;
}
}
...
}
নিচের অধ্যায়ের চিত্রটি এই পদ্ধতিকে কল করে এটা যাচাই করতে যে গুগল প্লে সার্ভিস রয়েছে।
একটি Activity বা Fragment থেকে আপডেট রিকোয়েস্ট পাঠান যা লোকেশন সার্ভিস কর্তৃক চাওয়া কলব্যাক পদ্ধতি বাস্তবায়ন করে। রিকোয়েস্ট করা একটি আসিঙ্খ্রোনাস প্রক্রিয়া যা শুরু হয় যখন আপনি একটি একটিভিটি রিকগনিশন ক্লায়েন্টে একটি সংযোগ রিকোয়েস্ট করেন। যখন ক্লায়েন্ট সংযুক্ত হয়, লোকেশন সার্ভিস আপনার onConnected()এর বাস্তবায়ন আহবান করে। এই পদ্ধতিতে আপনি লোকেশন সার্ভিসে আপডেট রিকোয়েস্ট পাঠাতে পারেন; এই রিকোয়েস্ট সিঙ্খ্রোনাস। যখনই আপনি রিকোয়েস্ট করে থাকবেন, আপনি ক্লায়েন্টটি বিচ্ছিন্ন করতে পারবেন।
এই প্রক্রিয়া নিচের চিত্রটিতে আলোচনা করা হয়েছে।
একটি FragmentActivity বা Fragment নির্ধারণ করুন যা নিচের ইন্টারফেসগুলো বাস্তবায়ন করে:
ConnectionCallbacks
পদ্ধতি নির্দিষ্ট করে যা লোকেশন সার্ভিস কল করে যখন ক্লায়েন্ট যুক্ত হয় বা বিযুক্ত হয়।
OnConnectionFailedListener
পদ্ধতি নির্দিষ্ট করে যা লোকেশন সার্ভিস কল করে যদি একটি এরর সংঘটিত করে যখন ক্লায়েন্ট সংযুক্ত করার চেষ্টা করে।
উদাহরণ:
public class MainActivity extends FragmentActivity implements
ConnectionCallbacks, OnConnectionFailedListener {
...
}
পরবর্তীতে, বৈশ্বিক ভেরিয়েবল এবং কনসট্যান্ট নির্ধারণ করুন। আপডেট ইন্টারভ্যালের জন্য কনসট্যানন্টস নির্ধারণ করুন, একটিভিটি রিকগনিশন ক্লঅয়েন্টের জন্য একটি ভেরিয়েবল যোগ করুন এবং আরেকটি PendingIntent এর জন্য যা লোকেশন সার্ভিস আপনার অ্যাপে আপডেট পঠানোর কাজে ব্যবহার করে:
public class MainActivity extends FragmentActivity implements
ConnectionCallbacks, OnConnectionFailedListener {
...
// Constants that define the activity detection interval
public static final int MILLISECONDS_PER_SECOND = 1000;
public static final int DETECTION_INTERVAL_SECONDS = 20;
public static final int DETECTION_INTERVAL_MILLISECONDS =
MILLISECONDS_PER_SECOND * DETECTION_INTERVAL_SECONDS;
...
/*
* Store the PendingIntent used to send activity recognition events
* back to the app
*/
private PendingIntent mActivityRecognitionPendingIntent;
// Store the current activity recognition client
private ActivityRecognitionClient mActivityRecognitionClient;
...
}
onCreate()এ, একটিভিটি রিকগনিশন ক্লায়েন্ট এবং PendingIntent ইনসটেনসিয়েট করুন:
public class MainActivity extends FragmentActivity implements
ConnectionCallbacks, OnConnectionFailedListener {
...
@Override
onCreate(Bundle savedInstanceState) {
...
/*
* Instantiate a new activity recognition client. Since the
* parent Activity implements the connection listener and
* connection failure listener, the constructor uses "this"
* to specify the values of those parameters.
*/
mActivityRecognitionClient =
new ActivityRecognitionClient(mContext, this, this);
/*
* Create the PendingIntent that Location Services uses
* to send activity recognition updates back to this app.
*/
Intent intent = new Intent(
mContext, ActivityRecognitionIntentService.class);
/*
* Return a PendingIntent that starts the IntentService.
*/
mActivityRecognitionPendingIntent =
PendingIntent.getService(mContext, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
...
}
...
}
একটি পদ্ধতি নির্ধারণ করুন যা একটিভিটি রিকগনিশন আপডেট রিকোয়েস্ট করে। পদ্ধতিটিতে লোকেশন সার্ভিসে একটি সংযোগ (কানেকশন) রিকোয়েস্ট করুন। আপনি আপনার একটিভিটির যে কোন জায়গা থেকে এই পদ্ধতি কল করতে পারেন; এর উদ্দেশ্য হচ্ছে আপডেট রিকোয়েস্ট তলব করা মেথড কলস চেইন শুরু করে।
রেস কনডিশন যা উদ্ভুত হতে পারে একটি শেষ হওয়ার আগেই আপনি যদি অন্য একটি রিকোয়েস্ট শুরু করার চেষ্টা করেন, এই কনডিশন থেকে রক্ষা করতে, একটি বুলিয়ান ফ্ল্যাগ নির্ধারণ করুন যা বর্তমান রিকোয়েস্টের অবস্থাকে অনুসরণ করে। যখন একটি রিকোয়েস্ট শুরু করবেন ফ্লাগটিকে true এ সেট করুন, এবং যখন রিকোয়েস্ট শেষ হবে এটাকে false এ সেট করুন।
নিচের চিত্রটি দেখাবে কীভাবে আপডেটের জন্য একটি রিকোয়েস্ট শুরু করতে হয়:
public class MainActivity extends FragmentActivity implements
ConnectionCallbacks, OnConnectionFailedListener {
...
// Global constants
...
// Flag that indicates if a request is underway.
private boolean mInProgress;
...
@Override
onCreate(Bundle savedInstanceState) {
...
// Start with the request flag set to false
mInProgress = false;
...
}
...
/**
* Request activity recognition updates based on the current
* detection interval.
*
*/
public void startUpdates() {
// Check for Google Play services
if (!servicesConnected()) {
return;
}
// If a request is not already underway
if (!mInProgress) {
// Indicate that a request is in progress
mInProgress = true;
// Request a connection to Location Services
mActivityRecognitionClient.connect();
//
} else {
/*
* A request is already underway. You can handle
* this situation by disconnecting the client,
* re-setting the flag, and then re-trying the
* request.
*/
}
}
...
}
onConnected()বাস্তবায়ন করুন। এই পদ্ধতিতে লোকেশন সার্ভিস থেকে একটিভিটি রিকগনিশন আপডেট গ্রহণ করুন। যখন লোকেশন সার্ভিস ক্লায়েন্টে সংযোগ শেষ করে এবং onConnected()কল করে, আপডেট রিকোয়েস্ট তাৎক্ষণিকভাবে কল হয়ে থাকে:
public class MainActivity extends FragmentActivity implements
ConnectionCallbacks, OnConnectionFailedListener {
...
/*
* Called by Location Services once the location client is connected.
*
* Continue by requesting activity updates.
*/
@Override
public void onConnected(Bundle dataBundle) {
/*
* Request activity recognition updates using the preset
* detection interval and PendingIntent. This call is
* synchronous.
*/
mActivityRecognitionClient.requestActivityUpdates(
DETECTION_INTERVAL_MILLISECONDS,
mActivityRecognitionPendingIntent);
/*
* Since the preceding call is synchronous, turn off the
* in progress flag and disconnect the client
*/
mInProgress = false;
mActivityRecognitionClient.disconnect();
}
...
}
কিছু ক্ষেত্রে আপনি disconnect()কল করার পূর্বে লোকেশন সার্ভিস একটিভিটি রিকগনিশন ক্লায়েন্ট থেকে বিচ্ছিন্ন হতে পারে। এই অবস্থা ব্যবস্থাপনা করতে, onDisconnect()বাস্তবায়ন করুন। এই পদ্ধতিতে, একটি রিকোয়েস্ট কোন অগ্রগতির মধ্যে নেই এটা নির্দেশ করতে রিকোয়েস্ট ফ্ল্যাগ সেট করুন এবং ক্লায়েন্ট ডিলিট করুন:
public class MainActivity extends FragmentActivity implements
ConnectionCallbacks, OnConnectionFailedListener {
...
/*
* Called by Location Services once the activity recognition
* client is disconnected.
*/
@Override
public void onDisconnected() {
// Turn off the request flag
mInProgress = false;
// Delete the client
mActivityRecognitionClient = null;
}
...
}
লোকেশন সার্ভিস থেকে স্বাভাবিক কলব্যাক ব্যবস্থাপনা ছাড়াও, আপনাকে একটি কলব্যাক পদ্ধতি প্রদান করতে হবে যা লোকেশন সার্ভিস কল করে যদি একটি কানেকশন এরর সংঘটিত হয়। এই কলব্যাক পদ্ধতি DialogFragment ক্লাস পূণর্ব্যবহার করতে পারে যা আপনি গুগল প্লে সার্ভিস চেক করার জন্য নির্ধারণ করেছিলেন। আপনি onActivityResult() যা যে কোন গুগল প্লে সার্ভিস রেজাল্ট যা ঘটে যখন ইউজার এরর ডায়লোগের সাথে যোগাযোগ করে তা গ্রহণ করে তার জন্য যে ওভাররাইড নির্ধারণ করেছিলেন তার পূণর্ব্যবহারও করতে পারেন যা। নিচের চিত্রটি কলব্যাক পদ্ধতির একটি নমুনা বাস্তবায়ন দেখায়:
public class MainActivity extends FragmentActivity implements
ConnectionCallbacks, OnConnectionFailedListener {
...
// Implementation of OnConnectionFailedListener.onConnectionFailed
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// Turn off the request flag
mInProgress = false;
/*
* If the error has a resolution, start a Google Play services
* activity to resolve it.
*/
if (connectionResult.hasResolution()) {
try {
connectionResult.startResolutionForResult(
this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
} catch (SendIntentException e) {
// Log the error
e.printStackTrace();
}
// If no resolution is available, display an error dialog
} else {
// Get the error code
int errorCode = connectionResult.getErrorCode();
// Get the error dialog from Google Play services
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
errorCode,
this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
// If Google Play services can provide an error dialog
if (errorDialog != null) {
// Create a new DialogFragment for the error dialog
ErrorDialogFragment errorFragment =
new ErrorDialogFragment();
// Set the dialog in the DialogFragment
errorFragment.setDialog(errorDialog);
// Show the error dialog in the DialogFragment
errorFragment.show(
getSupportFragmentManager(),
"Activity Recognition");
}
}
...
}
...
}