/*
* Copyright (C) 2016 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.apps.santatracker.invites;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import com.google.android.apps.santatracker.common.R;
import com.google.android.apps.santatracker.util.MeasurementManager;
import com.google.android.gms.appinvite.AppInvite;
import com.google.android.gms.appinvite.AppInviteInvitation;
import com.google.android.gms.appinvite.AppInviteInvitationResult;
import com.google.android.gms.appinvite.AppInviteReferral;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.firebase.analytics.FirebaseAnalytics;
public class AppInvitesFragment extends Fragment implements
GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = "AppInvitesFragment";
private static final String FRAGMENT_TAG = "AppInvitesFragment";
private static final int AUTOMANAGE_ID = 107;
private static final int RC_INVITE = 9007;
public static final Uri BASE_URI = Uri.parse("https://google.com/santatracker/android/");
private GoogleApiClient mGoogleApiClient;
private FirebaseAnalytics mMeasurement;
public interface GetInvitationCallback {
void onInvitation(String invitationId, String deepLink);
}
public static AppInvitesFragment getInstance(FragmentActivity activity) {
FragmentManager fm = activity.getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
AppInvitesFragment result = null;
Fragment fragment = fm.findFragmentByTag(FRAGMENT_TAG);
if (fragment == null) {
result = new AppInvitesFragment();
ft.add(result, FRAGMENT_TAG).disallowAddToBackStack().commit();
} else {
result = (AppInvitesFragment) fragment;
}
return result;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Initialize app measurement.
mMeasurement = FirebaseAnalytics.getInstance(getActivity());
// Api client for AppInvites.
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addOnConnectionFailedListener(this)
.enableAutoManage(getActivity(), AUTOMANAGE_ID, this)
.addApi(AppInvite.API)
.build();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_INVITE) {
String[] ids = AppInviteInvitation.getInvitationIds(resultCode, data);
Log.d(TAG, "onActivityResult:" + ids);
}
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.w(TAG, "onConnectionFailed:" + connectionResult);
}
/**
* Send an invite with a deep link into a game.
* @param gameName a human-readable name for the game, to be displayed in the invitation UI.
* @param gameId an identifier for the game to be appended to
* http://google.com/santatracker/android/. The game should be a registered
* handler for this URL in the Android Manifest.
* @param score the inviting user's game score, which will be pre-populated in the
* invitation message.
*/
public void sendGameInvite(String gameName, String gameId, int score) {
Uri uri = BASE_URI.buildUpon()
.appendPath(gameId)
.appendQueryParameter("score", Integer.toString(score))
.build();
sendInvite(getString(R.string.invite_message_game_fmt, score, gameName), uri);
MeasurementManager.recordInvitationSent(mMeasurement, "game", uri.toString());
}
public void sendGenericInvite() {
Uri uri = BASE_URI;
sendInvite(getString(R.string.invite_message_generic), uri);
MeasurementManager.recordInvitationSent(mMeasurement, "generic", uri.toString());
}
public void sendInvite(String message, Uri uri) {
// If the message is too long, just cut it short and add ellipses. This is something that
// only occurs in some translations and we do not have a better mitigation method. The
// alternative is an ugly IllegalArgumentException from the builder.
int maxLength = AppInviteInvitation.IntentBuilder.MAX_MESSAGE_LENGTH;
if (message.length() > maxLength) {
String suffix = "...";
String prefix = message.substring(0, maxLength - suffix.length());
message = prefix + suffix;
}
Intent inviteIntent = new AppInviteInvitation.IntentBuilder(getString(R.string.invite_title))
.setMessage(message)
.setDeepLink(uri)
.build();
startActivityForResult(inviteIntent, RC_INVITE);
}
public void getInvite(final GetInvitationCallback callback, final boolean launchDeepLink) {
// Using "null, false" as arguments here to avoid a known memory leak issue in
// AppInvites. Should be fixed in Google Play services v10.4.0.
final Activity activity = getActivity();
AppInvite.AppInviteApi.getInvitation(mGoogleApiClient, null, false)
.setResultCallback(new ResultCallback<AppInviteInvitationResult>() {
@Override
public void onResult(AppInviteInvitationResult appInviteInvitationResult) {
Log.d(TAG, "getInvite:" + appInviteInvitationResult.getStatus());
if (callback != null && appInviteInvitationResult.getStatus().isSuccess()) {
// Report the callback.
Intent intent = appInviteInvitationResult.getInvitationIntent();
String invitiationId = AppInviteReferral.getInvitationId(intent);
String deepLink = AppInviteReferral.getDeepLink(intent);
callback.onInvitation(invitiationId, deepLink);
// Record invitation receipt event.
MeasurementManager.recordInvitationReceived(mMeasurement, deepLink);
// Launch the deep link (see above note on why we don't do this
// automatically)
if (launchDeepLink) {
try {
activity.startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.w(TAG, "No handler for deep link", e);
}
}
}
}
});
}
}