How to recreate the spotify demo on android studio 2? - java

I've tried following the instructions on the spotify android sdk site and when I tested it on my emulator, all I got was a white screen. I understand the demo code is supposed to pull up a login request and then play a song track if the login was successful am I right?
Here's my code for reference
package com.example.wilsonler.spotifytest2;
import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.spotify.sdk.android.player.Spotify;
import com.spotify.sdk.android.authentication.AuthenticationClient;
import com.spotify.sdk.android.authentication.AuthenticationRequest;
import com.spotify.sdk.android.authentication.AuthenticationResponse;
import com.spotify.sdk.android.player.Config;
import com.spotify.sdk.android.player.ConnectionStateCallback;
import com.spotify.sdk.android.player.Player;
import com.spotify.sdk.android.player.PlayerNotificationCallback;
import com.spotify.sdk.android.player.PlayerState;
public class MainActivity extends Activity implements
PlayerNotificationCallback, ConnectionStateCallback {
// TODO: Replace with your client ID
private static final String CLIENT_ID = "3488191ba4e54c958f83e74b240c528c";
// TODO: Replace with your redirect URI
private static final String REDIRECT_URI = "http://localhost:1034://authenticationResponse";
// Request code that will be passed together with authentication result to the onAuthenticationResult callback
// Can be any integer
private static final int REQUEST_CODE = 1337;
private Player mPlayer;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AuthenticationRequest.Builder builder =
new AuthenticationRequest.Builder(CLIENT_ID, AuthenticationResponse.Type.TOKEN, REDIRECT_URI);
builder.setScopes(new String[]{"user-read-private", "streaming"});
AuthenticationRequest request = builder.build();
AuthenticationClient.openLoginActivity(this, REQUEST_CODE, request);
}
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
// Check if result comes from the correct activity
if (requestCode == REQUEST_CODE) {
AuthenticationResponse response = AuthenticationClient.getResponse(resultCode, intent);
if (response.getType() == AuthenticationResponse.Type.TOKEN) {
Config playerConfig = new Config(this, response.getAccessToken(), CLIENT_ID);
mPlayer = Spotify.getPlayer(playerConfig, this, new Player.InitializationObserver() {
#Override
public void onInitialized(Player player) {
mPlayer.addConnectionStateCallback(MainActivity.this);
mPlayer.addPlayerNotificationCallback(MainActivity.this);
mPlayer.play("spotify:track:2TpxZ7JUBn3uw46aR7qd6V");
}
#Override
public void onError(Throwable throwable) {
Log.e("MainActivity", "Could not initialize player: " + throwable.getMessage());
}
});
}
}
}
#Override
public void onLoggedIn() {
Log.d("MainActivity", "User logged in");
}
#Override
public void onLoggedOut() {
Log.d("MainActivity", "User logged out");
}
#Override
public void onLoginFailed(Throwable error) {
Log.d("MainActivity", "Login failed");
}
#Override
public void onTemporaryError() {
Log.d("MainActivity", "Temporary error occurred");
}
#Override
public void onConnectionMessage(String message) {
Log.d("MainActivity", "Received connection message: " + message);
}
#Override
public void onPlaybackEvent(EventType eventType, PlayerState playerState) {
Log.d("MainActivity", "Playback event received: " + eventType.name());
switch (eventType) {
// Handle event type as necessary
default:
break;
}
}
#Override
public void onPlaybackError(ErrorType errorType, String errorDetails) {
Log.d("MainActivity", "Playback error received: " + errorType.name());
switch (errorType) {
// Handle error type as necessary
default:
break;
}
}
#Override
protected void onDestroy() {
// VERY IMPORTANT! This must always be called or else you will leak resources
Spotify.destroyPlayer(this);
super.onDestroy();
}
}

Related

Sinch not starting

This is such a basic issue that I am not sure what I could possibly be doing wrong. Sinch is not starting for me and I don't know why. I don't have enough experience with Sinch to diagnose why a basic command is not doing what it is supposed to do. Here's what I have:
I am trying to start and making the call from the Calling.java class. The code is as follows:
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.sinch.android.rtc.calling.Call;
import com.squareup.picasso.Picasso;
import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
public class Calling extends CallActivity {
private String calleeID;
private TextView serviceName;
Bundle callDetails;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calling);
callDetails = getIntent().getBundleExtra("callDetails");
//Setup end button
Button endCallButton = findViewById(R.id.endcall);
endCallButton.setOnClickListener(v -> endCall());
}
private void endCall() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
finishActivity(FLAG_ACTIVITY_PREVIOUS_IS_TOP);
finish();
}
// invoked when the connection with SinchServer is established
#Override
protected void onServiceConnected() {
//Setup Calling Screen
ImageView avatar = findViewById(R.id.dialingAvatar);
Picasso.get().load(callDetails.getString("Logo")).into(avatar);
TextView midScreenName = findViewById(R.id.memberName);
midScreenName.setText(callDetails.getString("Name"));
serviceName = findViewById(R.id.serviceName);
serviceName.setText(callDetails.getString("Service"));
TextView ratings = findViewById(R.id.rating);
ratings.setText(callDetails.getString("Rating") + " ★");
//Get CallerID and CalleeID
calleeID = callDetails.getString("CalleeID");
//Start sinch Service
if(!getSinchServiceInterface().isStarted()){
getSinchServiceInterface().startClient(callDetails.getString("CallerID"));
Call call = getSinchServiceInterface().callUserVideo(calleeID);
Intent callServiceScreen = new Intent(this, ServiceCallActivity.class);
callDetails.putString(SinchService.CALL_ID, call.getCallId());
callServiceScreen.putExtra("Call Details", callDetails);
startActivity(callServiceScreen);
}
}
#Override
public void onDestroy() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
super.onDestroy();
}
}
I am coming to Calling.java from Precall.java the code for that is:
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.sinch.android.rtc.SinchError;
import com.squareup.picasso.Picasso;
import org.json.JSONObject;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class precall extends CallActivity implements SinchService.StartFailedListener {
private Bundle memberDetails;
private String url;
private Button cancel;
private Button call;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_precall);
//url
url = apiCallPoints.userInfo;
//Set Member Text
memberDetails = getIntent().getBundleExtra("Member");
//Populate screen
ImageView avatar = findViewById(R.id.avatar);
Picasso.get().load(memberDetails.getString("Logo")).into(avatar);
TextView memberName = findViewById(R.id.membername);
memberName.setText(memberDetails.getString("Name"));
TextView rating = findViewById(R.id.rating);
rating.setText(memberDetails.getString("Rating") + " ★");
TextView serviceName = findViewById(R.id.servicename);
serviceName.setText(memberDetails.getString("Service"));
TextView overview = findViewById(R.id.overview);
overview.setText(memberDetails.getString("Overview"));
//Add button clicks
cancel = findViewById(R.id.cancel_button);
cancel.setOnClickListener(view -> finish());
cancel.setEnabled(false);
call = findViewById(R.id.yes_button);
call.setOnClickListener(view -> {
goToCalling();
});
call.setEnabled(false);
setHomeBar();
}
//this method is invoked when the connection is established with the SinchService
#Override
protected void onServiceConnected() {
call.setEnabled(true);
cancel.setEnabled(true);
getSinchServiceInterface().setStartListener(this);
}
#Override
protected void onPause() {
super.onPause();
}
#Override
public void onStartFailed(SinchError error) {
}
//Invoked when just after the service is connected with Sinch
#Override
public void onStarted() {
}
private void goToCalling() {
//Async search
CallBackendSync callBackendSync = new CallBackendSync();
Object [] params = {url, memberDetails};
callBackendSync.execute(params);
}
private void setHomeBar() {
final Button home = findViewById(R.id.home_button);
home.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
startActivity(new Intent(precall.this, SecondActivity.class));
}
});
final Button favourites = findViewById(R.id.star_button);
favourites.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
startActivity(new Intent(precall.this, Favourite_Page.class));
}
});
final Button profile_page = findViewById(R.id.person_button);
profile_page.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
startActivity(new Intent(getApplicationContext(), Profile.class));
}
});
final Button notifications = findViewById(R.id.notification_button);
notifications.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
startActivity(new Intent(precall.this, Notification_Page.class));
}
});
final Button service = findViewById(R.id.service_button);
service.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
startActivity(new Intent(precall.this, services.class));
}
});
}
class CallBackendSync extends AsyncTask {
OkHttpClient client = new OkHttpClient();
#Override
protected Object doInBackground(Object [] objects) {
String url = (String) objects[0];
Bundle memberDetails = (Bundle) objects[1];
//Get access token from shared preference
isLoggedIn loggedIn = new isLoggedIn(getApplicationContext());
String token = loggedIn.getToken();
if(token != null){
//Create request
Request request = new Request.Builder()
.url(url)
.addHeader("Authorization", "Bearer " + token)
.addHeader("Accept", "application/json")
.build();
try {
Response response = client.newCall(request).execute();
JSONObject results = new JSONObject(response.body().string());
String UserID = results.getString("UserId");
memberDetails.putString("CallerID", UserID);
Intent callIntent = new Intent(precall.this, Calling.class);
callIntent.putExtra("callDetails", memberDetails);
startActivity(callIntent);
return results;
}catch (Exception e){
e.printStackTrace();
}
} else {
startActivity(new Intent(precall.this, Login_page.class));
}
return null;
}
protected void onPostExecute(String s){
super.onPostExecute(s);
}
}
}
The failure is happening in SinchService.java
import com.sinch.android.rtc.AudioController;
import com.sinch.android.rtc.ClientRegistration;
import com.sinch.android.rtc.Sinch;
import com.sinch.android.rtc.SinchClient;
import com.sinch.android.rtc.SinchClientListener;
import com.sinch.android.rtc.SinchError;
import com.sinch.android.rtc.video.VideoController;
import com.sinch.android.rtc.calling.Call;
import com.sinch.android.rtc.calling.CallClient;
import com.sinch.android.rtc.calling.CallClientListener;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class SinchService extends Service {
private static final String APP_KEY = "is correct";
private static final String APP_SECRET = "is correct";
//private static final String ENVIRONMENT = "clientapi.sinch.com";
private static final String ENVIRONMENT = "sandbox.sinch.com";
public static final String CALL_ID = "CALL_ID";
static final String TAG = SinchService.class.getSimpleName();
private SinchServiceInterface mSinchServiceInterface = new SinchServiceInterface();
private SinchClient mSinchClient = null;
private String mUserId = "";
private StartFailedListener mListener;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
if(mSinchClient != null){
mSinchClient.terminate();
}
super.onDestroy();
}
private void start(String userName) {
mUserId = userName;
mSinchClient = Sinch.getSinchClientBuilder().context(getApplicationContext())
.applicationKey(APP_KEY)
.applicationSecret(APP_SECRET)
.environmentHost(ENVIRONMENT)
.userId(userName)
.enableVideoCalls(true)
.build();
mSinchClient.setSupportCalling(true);
mSinchClient.startListeningOnActiveConnection();
mSinchClient.addSinchClientListener(new MySinchClientListener());
mSinchClient.getCallClient().addCallClientListener(new SinchCallClientListener());
mSinchClient.checkManifest();
mSinchClient.start();
System.out.println("Is started: " + mSinchClient.isStarted());
}
private void stop() {
if(mSinchClient != null){
mSinchClient.terminate();
}
}
private boolean isStarted() {
if(mSinchClient != null){
return mSinchClient.isStarted();
} else {
return false;
}
}
#Override
public IBinder onBind(Intent intent) {
return mSinchServiceInterface;
}
public class SinchServiceInterface extends Binder {
public Call callUserVideo(String userId) {
return mSinchClient.getCallClient().callUserVideo(userId);
}
public String getUserName() {
return mUserId;
}
public boolean isStarted() {
return SinchService.this.isStarted();
}
public void startClient(String userName) {
start(userName);
}
public void stopClient() {
stop();
}
public void setStartListener(StartFailedListener listener) {
mListener = listener;
}
public Call getCall(String callId) {
return mSinchClient.getCallClient().getCall(callId);
}
public VideoController getVideoController() {
return mSinchClient.getVideoController();
}
public AudioController getAudioController() {
return mSinchClient.getAudioController();
}
}
public interface StartFailedListener {
void onStartFailed(SinchError error);
void onStarted();
}
private class MySinchClientListener implements SinchClientListener {
#Override
public void onClientFailed(SinchClient client, SinchError error) {
if (mListener != null) {
mListener.onStartFailed(error);
}
mSinchClient.terminate();
mSinchClient = null;
}
#Override
public void onClientStarted(SinchClient client) {
Log.d(TAG, "SinchClient started");
if (mListener != null) {
mListener.onStarted();
}
}
#Override
public void onClientStopped(SinchClient client) {
Log.d(TAG, "SinchClient stopped");
}
#Override
public void onLogMessage(int level, String area, String message) {
switch (level) {
case Log.DEBUG:
Log.d(area, message);
break;
case Log.ERROR:
Log.e(area, message);
break;
case Log.INFO:
Log.i(area, message);
break;
case Log.VERBOSE:
Log.v(area, message);
break;
case Log.WARN:
Log.w(area, message);
break;
}
}
#Override
public void onRegistrationCredentialsRequired(SinchClient client,
ClientRegistration clientRegistration) {
}
}
private class SinchCallClientListener implements CallClientListener {
#Override
public void onIncomingCall(CallClient callClient, Call call) {
Log.d(TAG, "Incoming call");
Intent intent = new Intent(SinchService.this, Calling.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
SinchService.this.startActivity(intent);
}
}
}
And the base activity is CallActivity.java
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.sinch.android.rtc.calling.Call;
import com.squareup.picasso.Picasso;
import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
public class Calling extends CallActivity {
private String calleeID;
private TextView serviceName;
Bundle callDetails;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calling);
callDetails = getIntent().getBundleExtra("callDetails");
//Setup end button
Button endCallButton = findViewById(R.id.endcall);
endCallButton.setOnClickListener(v -> endCall());
}
private void endCall() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
finishActivity(FLAG_ACTIVITY_PREVIOUS_IS_TOP);
finish();
}
// invoked when the connection with SinchServer is established
#Override
protected void onServiceConnected() {
//Setup Calling Screen
ImageView avatar = findViewById(R.id.dialingAvatar);
Picasso.get().load(callDetails.getString("Logo")).into(avatar);
TextView midScreenName = findViewById(R.id.memberName);
midScreenName.setText(callDetails.getString("Name"));
serviceName = findViewById(R.id.serviceName);
serviceName.setText(callDetails.getString("Service"));
TextView ratings = findViewById(R.id.rating);
ratings.setText(callDetails.getString("Rating") + " ★");
//Get CallerID and CalleeID
calleeID = callDetails.getString("CalleeID");
//Start sinch Service
if(!getSinchServiceInterface().isStarted()){
getSinchServiceInterface().startClient(callDetails.getString("CallerID"));
Call call = getSinchServiceInterface().callUserVideo(calleeID);
Intent callServiceScreen = new Intent(this, ServiceCallActivity.class);
callDetails.putString(SinchService.CALL_ID, call.getCallId());
callServiceScreen.putExtra("Call Details", callDetails);
startActivity(callServiceScreen);
}
}
#Override
public void onDestroy() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
super.onDestroy();
}
}
I have been banging my head against this but I cannot figure out what's wrong. I sure it's something stupid and obvious that I can't see because I am too close to the code. But any ideas you guys have would be very helpful!
It looks like you are not waiting for it to start before you try to make a call. We recommend to start the service when the app starts. If you dont do that you need to wait or the onStarted event in the service for fire

what is the 101 error code mean in in-app-billing v3 library?

I am using in app billing v3 library, it is always get error
and error code is 101
What does this error code mean?
some details:
I am a developer working from Palestine and working on an app uploadded on Indian google play account
I created activity that included three buttons to purchase remove Ads
-the first button to subscribe one month
-the second to subscribe one year
-the third to purchase lifetime
I used this library 'com.anjlab.android.iab.v3:library:1.0.44'
I created product in google play console and its name PRODUCT_ID
this product will purchased when user click on button lifeTime
and I created two subscriptions
-the first's name is SUBSCRIPTION_MONTH_ID
and will be purchased when the user click on oneMonth button
-the second's name is SUBSCRIPTION_YEAR_ID
and will be purchased when the user click on oneYear button
this the code that I used
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.anjlab.android.iab.v3.BillingProcessor;
import com.anjlab.android.iab.v3.TransactionDetails;
public class InAppBilling extends AppCompatActivity{
BillingProcessor bp;
private static final String PRODUCT_ID = "****";
private static final String SUBSCRIPTION_MONTH_ID = "***";
private static final String SUBSCRIPTION_YEAR_ID = "***";
private static final String LICENSE_KEY = "*****";
private static final String MERCHANT_ID = "**";
Button oneMonth, oneYear, lifeTime;
int flag;
String android_id;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_in_app_purchase);
flag = 0;
android_id = Settings.Secure.getString(getApplicationContext().getContentResolver(),
Settings.Secure.ANDROID_ID);
final Toolbar toolbar = findViewById(R.id.toolbar);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
toolbar.setTitle("Remove Ads");
}
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
if(!BillingProcessor.isIabServiceAvailable(this)) {
Toast.makeText(this, "In-app billing service is unavailable, please upgrade Android Market/Play to version >= 3.9.16", Toast.LENGTH_SHORT).show();
}
bp = new BillingProcessor(this, LICENSE_KEY, MERCHANT_ID, new BillingProcessor.IBillingHandler() {
#Override
public void onProductPurchased(String productId, TransactionDetails details) {
Toast.makeText(InAppBilling.this, "successfully purchased, restart the app please", Toast.LENGTH_SHORT).show();
}
#Override
public void onBillingError(int errorCode, Throwable error) {
Toast.makeText(InAppBilling.this, "Error Billing", Toast.LENGTH_SHORT).show();
Log.e("nourbilling", "onBillingError: errorCode: "+errorCode+" error: "+error);
}
#Override
public void onBillingInitialized() {
}
#Override
public void onPurchaseHistoryRestored() {
for(String sku : bp.listOwnedProducts())
Log.d("nourbilling", "Owned Managed Product: " + sku);
for(String sku : bp.listOwnedSubscriptions())
Log.d("nourbilling", "Owned Subscription: " + sku);
}
});
oneMonth = findViewById(R.id.oneMonth);
oneYear = findViewById(R.id.oneYear);
lifeTime = findViewById(R.id.lifetime);
final Activity activity = this;
oneMonth.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
flag = 1;
createDialog(savedInstanceState, activity).show();
}
});
oneYear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
flag = 2;
createDialog(savedInstanceState, activity).show();
}
});
lifeTime.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
flag = 3;
createDialog(savedInstanceState, activity).show();
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (!bp.handleActivityResult(requestCode, resultCode, data))
super.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onDestroy() {
if (bp != null)
bp.release();
super.onDestroy();
}
public Dialog createDialog(Bundle savedInstanceState, final Activity activity) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("are you sure to remove ads by billing?")
.setPositiveButton("yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (flag == 1) {
bp.subscribe(activity, SUBSCRIPTION_MONTH_ID);
} else if (flag == 2) {
bp.subscribe(activity, SUBSCRIPTION_YEAR_ID);
} else if (flag == 3) {
bp.purchase(activity, PRODUCT_ID);
}
}
})
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
return builder.create();
}
}
can you help me, please?

Android Studio cannot resolve com.google.android.gms.nearby.messages.SubscribeOptions.Builder

I am trying to use Google's Nearby Messages API for the first time. I downloaded some source code from GitHub and tried to compile it using Android Studio. There is an import that Android Studio cannot resolve:
import com.google.android.gms.nearby.messages.SubscribeOptions;
My Gradle file defines the following dependencies:
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.2.0'
compile 'com.google.android.gms:play-services:7.8.0'
compile 'com.google.android.gms:play-services-nearby:7.8.0'
and this is the Activity in which I am using the aforementioned library:
package com.example.android.nearbybeacons;
import android.Manifest;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
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.android.gms.common.api.Status;
import com.google.android.gms.nearby.Nearby;
import com.google.android.gms.nearby.messages.Message;
import com.google.android.gms.nearby.messages.MessageListener;
import com.google.android.gms.nearby.messages.Strategy;
import com.google.android.gms.nearby.messages.SubscribeOptions;
public class MainActivity extends AppCompatActivity implements
AdapterView.OnItemClickListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final String TAG =
MainActivity.class.getSimpleName();
private static final int REQUEST_RESOLVE_ERROR = 100;
private static final int REQUEST_PERMISSION = 42;
private GoogleApiClient mGoogleApiClient;
private ArrayAdapter<OfferBeacon> mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView list = (ListView) findViewById(R.id.list);
mAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
list.setAdapter(mAdapter);
list.setOnItemClickListener(this);
//Construct a connection to Play Services
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Nearby.MESSAGES_API)
.build();
//When launching from a notification link
if (BeaconService.ACTION_DISMISS.equals(getIntent().getAction())) {
//Fire a clear action to the service
Intent intent = new Intent(this, BeaconService.class);
intent.setAction(BeaconService.ACTION_DISMISS);
startService(intent);
}
}
#Override
protected void onStart() {
super.onStart();
//Initiate connection to Play Services
mGoogleApiClient.connect();
//The location permission is required on API 23+ to obtain BLE scan results
int result = ActivityCompat
.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);
if (result != PackageManager.PERMISSION_GRANTED) {
//Ask for the location permission
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
REQUEST_PERMISSION);
}
}
#Override
protected void onStop() {
super.onStop();
//Tear down Play Services connection
if (mGoogleApiClient.isConnected()) {
Log.d(TAG, "Un-subscribing…");
Nearby.Messages.unsubscribe(
mGoogleApiClient,
mMessageListener);
mAdapter.clear();
mGoogleApiClient.disconnect();
}
}
// This is called in response to a button tap in the system permissions dialog.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_RESOLVE_ERROR) {
if (resultCode == RESULT_OK) {
// Permission granted or error resolved successfully then we proceed
// with publish and subscribe..
subscribe();
} else {
// This may mean that user had rejected to grant nearby permission.
showToast("Failed to resolve error with code " + resultCode);
}
}
if (requestCode == REQUEST_PERMISSION) {
if (resultCode != RESULT_OK) {
showToast("We need location permission to get scan results!");
finish();
}
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
OfferBeacon item = mAdapter.getItem(position);
showToast(item.offer);
}
/* Nearby Messages Callbacks */
//NOTE: These callbacks are NOT triggered on the main thread!
private MessageListener mMessageListener = new MessageListener() {
// Called each time a new message is discovered nearby.
#Override
public void onFound(Message message) {
Log.i(TAG, "Found message: " + message);
final OfferBeacon beacon = new OfferBeacon(message);
runOnUiThread(new Runnable() {
#Override
public void run() {
mAdapter.add(beacon);
}
});
}
// Called when the publisher (beacon) is no longer nearby.
#Override
public void onLost(Message message) {
Log.i(TAG, "Lost message: " + message);
final OfferBeacon beacon = new OfferBeacon(message);
runOnUiThread(new Runnable() {
#Override
public void run() {
mAdapter.remove(beacon);
}
});
}
};
/* API Client Callbacks */
#Override
public void onConnected(Bundle bundle) {
//Once connected, we have to check that the user has opted in
Runnable runOnSuccess = new Runnable() {
#Override
public void run() {
//Subscribe once user permission is verified
subscribe();
}
};
ResultCallback<Status> callback =
new ErrorCheckingCallback(runOnSuccess);
Nearby.Messages.getPermissionStatus(mGoogleApiClient)
.setResultCallback(callback);
}
#Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "OnConnectionSuspended");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.w(TAG, "OnConnectionFailed");
}
private void subscribe() {
Log.d(TAG, "Subscribing…");
SubscribeOptions options = new SubscribeOptions.Builder()
.setStrategy(Strategy.BLE_ONLY)
.build();
//Active subscription for foreground messages
Nearby.Messages.subscribe(mGoogleApiClient,
mMessageListener, options);
//Passive subscription for background messages
Intent serviceIntent = new Intent(this, BeaconService.class);
PendingIntent trigger = PendingIntent.getService(this, 0,
serviceIntent, PendingIntent.FLAG_UPDATE_CURRENT);
ResultCallback<Status> callback = new BackgroundRegisterCallback();
Nearby.Messages.subscribe(mGoogleApiClient, trigger, options)
.setResultCallback(callback);
}
private class BackgroundRegisterCallback implements ResultCallback<Status> {
#Override
public void onResult(#NonNull Status status) {
//Validate if we were able to register for background scans
if (status.isSuccess()) {
Log.d(TAG, "Background Register Success!");
} else {
Log.w(TAG, "Background Register Error ("
+ status.getStatusCode() + "): "
+ status.getStatusMessage());
}
}
}
//ResultCallback triggered when to handle Nearby permissions check
private class ErrorCheckingCallback implements ResultCallback<Status> {
private final Runnable runOnSuccess;
private ErrorCheckingCallback(#Nullable Runnable runOnSuccess) {
this.runOnSuccess = runOnSuccess;
}
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess()) {
Log.i(TAG, "Permission status succeeded.");
if (runOnSuccess != null) {
runOnSuccess.run();
}
} else {
// Currently, the only resolvable error is that the device is not opted
// in to Nearby. Starting the resolution displays an opt-in dialog.
if (status.hasResolution()) {
try {
status.startResolutionForResult(MainActivity.this,
REQUEST_RESOLVE_ERROR);
} catch (IntentSender.SendIntentException e) {
showToastAndLog(Log.ERROR, "Request failed with exception: " + e);
}
} else {
showToastAndLog(Log.ERROR, "Request failed with : " + status);
}
}
}
}
private void showToast(String text) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
}
private void showToastAndLog(int logLevel, String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
Log.println(logLevel, TAG, message);
}
}
Can anyone tell me what I'm doing wrong?
My guess is that you will be able to resolve this by updating the Play Services version you are using from v7.8.0 to v8.4.0 (the latest version as of this answer date). The Nearby APIs were introduced in v7.8.0, at which time subscription could be accomplished using a method signature of the form
subscribe(GoogleApiClient, MessageListener, Strategy)
However, this method is now (in v8.4.0) marked as deprecated, and a new method with the following signature is recommended in its place:
subscribe (GoogleApiClient, MessageListener, SubscribeOptions)
Based on this information it seems fairly likely that the SubscribeOptions type was introduced whenever the previously-described deprecation took place, which was clearly post-v7.8.0.
See these docs for reference.

How to get emailid from Facebook Login in using facebook sdk version 3.22.0

I am using only one button when i click on the button then i want to get the email id.
Here is my code and get the ID and name, but emailid cannot get.I am using facebook sdk version 3.22.0 Please help me.
enter code here
package com.example.testintegration;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import org.json.JSONException;
import org.json.JSONObject;
import com.example.testfbintegration.R;
import com.facebook.Request;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.AsyncFacebookRunner.RequestListener;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;
import com.facebook.model.GraphUser;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
private static String APP_ID = "862722850469774"; // Replace with your App ID
// Instance of Facebook Class
private Facebook facebook = new Facebook(APP_ID);
private AsyncFacebookRunner mAsyncRunner;
String FILENAME = "AndroidSSO_data";
private SharedPreferences mPrefs;
// Buttons
Button btnFbLogin;
/*Button btnFbGetProfile;
Button btnPostToWall;
Button btnShowAccessTokens;*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnFbLogin = (Button) findViewById(R.id.btn_fblogin);
/*btnFbGetProfile = (Button) findViewById(R.id.btn_get_profile);
btnPostToWall = (Button) findViewById(R.id.btn_fb_post_to_wall);
btnShowAccessTokens = (Button) findViewById(R.id.btn_show_access_tokens);*/
mAsyncRunner = new AsyncFacebookRunner(facebook);
/**
* Login button Click event
* */
btnFbLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("Image Button", "button Clicked");
//loginToFacebook();
logfacebook();
}
});
/**
* Getting facebook Profile info
* *//*
btnFbGetProfile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getProfileInformation();
}
});
*//**
* Posting to Facebook Wall
* *//*
btnPostToWall.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
postToWall();
}
});
*//**
* Showing Access Tokens
* *//*
btnShowAccessTokens.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showAccessTokens();
}
});*/
}
public void logfacebook()
{
Session.openActiveSession(MainActivity.this, true, new Session.StatusCallback() {
// callback when session changes state
#Override
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
// make request to the /me API
Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
System.out.println(user.getName());
System.out.println(user.getBirthday());
System.out.println(user.getFirstName());
System.out.println(user.getLastName());
System.out.println(user.getLink());
System.out.println(user.getUsername());
System.out.println(user.getLocation());
System.out.println("facebook user id" + user.getId());
System.out.println(user.asMap().get("email").toString());
// Session.OpenRequest open = new Session.OpenRequest(Login)
}
}
});
}
}
});
}
/**
* Function to login into facebook
* */
public void loginToFacebook() {
mPrefs = getPreferences(MODE_PRIVATE);
String access_token = mPrefs.getString("access_token", null);
long expires = mPrefs.getLong("access_expires", 0);
if (access_token != null) {
facebook.setAccessToken(access_token);
btnFbLogin.setVisibility(View.INVISIBLE);
// Making get profile button visible
// btnFbGetProfile.setVisibility(View.VISIBLE);
// Making post to wall visible
//btnPostToWall.setVisibility(View.VISIBLE);
// Making show access tokens button visible
//btnShowAccessTokens.setVisibility(View.VISIBLE);
Log.d("FB Sessions", "" + facebook.isSessionValid());
}
if (expires != 0) {
facebook.setAccessExpires(expires);
}
if (!facebook.isSessionValid()) {
facebook.authorize(this,
new String[] { "email", "publish_actions" },
new DialogListener() {
#Override
public void onCancel() {
// Function to handle cancel event
}
#Override
public void onComplete(Bundle values) {
// Function to handle complete event
// Edit Preferences and update facebook acess_token
SharedPreferences.Editor editor = mPrefs.edit();
editor.putString("access_token",
facebook.getAccessToken());
editor.putLong("access_expires",
facebook.getAccessExpires());
editor.commit();
// Making Login button invisible
btnFbLogin.setVisibility(View.INVISIBLE);
// Making logout Button visible
// btnFbGetProfile.setVisibility(View.VISIBLE);
// Making post to wall visible
//btnPostToWall.setVisibility(View.VISIBLE);
// Making show access tokens button visible
//btnShowAccessTokens.setVisibility(View.VISIBLE);
}
#Override
public void onError(DialogError error) {
// Function to handle error
}
#Override
public void onFacebookError(FacebookError fberror) {
// Function to handle Facebook errors
}
});
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
facebook.authorizeCallback(requestCode, resultCode, data);
}
/**
* Get Profile information by making request to Facebook Graph API
* */
public void getProfileInformation() {
mAsyncRunner.request("me", new RequestListener() {
#Override
public void onComplete(String response, Object state) {
Log.d("Profile", response);
String json = response;
try {
// Facebook Profile JSON data
JSONObject profile = new JSONObject(json);
// getting name of the user
final String name = profile.getString("name");
// getting email of the user
final String email = profile.getString("email");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Name: " + name + "\nEmail: " + email, Toast.LENGTH_LONG).show();
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onIOException(IOException e, Object state) {
}
#Override
public void onFileNotFoundException(FileNotFoundException e,
Object state) {
}
#Override
public void onMalformedURLException(MalformedURLException e,
Object state) {
}
#Override
public void onFacebookError(FacebookError e, Object state) {
}
});
}
/**
* Function to post to facebook wall
* */
public void postToWall() {
// post on user's wall.
facebook.dialog(this, "feed", new DialogListener() {
#Override
public void onFacebookError(FacebookError e) {
}
#Override
public void onError(DialogError e) {
}
#Override
public void onComplete(Bundle values) {
}
#Override
public void onCancel() {
}
});
}
/**
* Function to show Access Tokens
* */
public void showAccessTokens() {
String access_token = facebook.getAccessToken();
Toast.makeText(getApplicationContext(),
"Access Token: " + access_token, Toast.LENGTH_LONG).show();
}
/**
* Function to Logout user from Facebook
* */
public void logoutFromFacebook() {
mAsyncRunner.logout(this, new RequestListener() {
#Override
public void onComplete(String response, Object state) {
Log.d("Logout from Facebook", response);
if (Boolean.parseBoolean(response) == true) {
runOnUiThread(new Runnable() {
#Override
public void run() {
// make Login button visible
btnFbLogin.setVisibility(View.VISIBLE);
// making all remaining buttons invisible
/*btnFbGetProfile.setVisibility(View.INVISIBLE);
btnPostToWall.setVisibility(View.INVISIBLE);
btnShowAccessTokens.setVisibility(View.INVISIBLE);*/
}
});
}
}
#Override
public void onIOException(IOException e, Object state) {
}
#Override
public void onFileNotFoundException(FileNotFoundException e,
Object state) {
}
#Override
public void onMalformedURLException(MalformedURLException e,
Object state) {
}
#Override
public void onFacebookError(FacebookError e, Object state) {
}
});
}
}
use this code.
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback() {
#Override
public void onSuccess(LoginResult result) {
new GraphRequest();
// SocialSdkPrefrences.getInstance().setAccessToken(result.getAccessToken().getToken());
GraphRequest request = GraphRequest.newMeRequest(result.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
Profile profile = Profile.getCurrentProfile();
FacebookGraphUser fbGraphUser = (FacebookGraphUser) JsonUtil.toModel(response.getRawResponse(), FacebookGraphUser.class);
if (fbGraphUser != null) {
String image_url = "http://graph.facebook.com/" + fbGraphUser.getId() + "/picture?type=large";
// UniversalImageLoaderUtil.loadImageWithDefaultImage(image_url, (ImageView) findViewById(R.id.user_image), null, R.drawable.place_holder_album);
User user=new User(fbGraphUser.getEmail(),image_url,profile.getName(),Long.parseLong(fbGraphUser.getId()));
Gson gson = new Gson();
Log.d("social", gson.toJson(user));
if (fbGraphUser.getEmail() != null) {
if (Util.isValidEmail(fbGraphUser.getEmail())) {
new SocialLogInAsyncTask(LoginActivity.this, user).execute();
} else {
Toast.showShortToast(LoginActivity.this, "You have not valid email,cant login");
}
} else {
Toast.showShortToast(LoginActivity.this, "You have not email,cant login");
}
} else {
Toast.showErrorToast(LoginActivity.this, R.string.error_signup);
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,email,gender,birthday,picture.width(300)");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
Log.d("tag", "cancel facebook login");
}
#Override
public void onError(FacebookException error) {
Log.d("tag", "error in login" + error.getMessage());
}
});
Please check this link of your answer & let me know if you find any problem in fb integration.
Unable to get emailId after login through fb in android
call this in your main Activity or the activity that is using FaceBookSignIn method
FacebookSdk.sdkInitialize(MainActivity.this);
add this method in your activity
public void FaceBookSignIn() {
callbackManager = CallbackManager.Factory.create();
loginType = Constants.loginTypeFaceBook;
LoginManager.getInstance().logInWithReadPermissions(MainActivity.this, Arrays.asList("email", "user_photos", "public_profile"));
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
DisplaySnackBar.display(getWindow().getDecorView().findViewById(android.R.id.content), "Success", true);
GraphRequest request = GraphRequest.newMeRequest(loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject jsonObject, GraphResponse graphResponse) {
try {
String email = jsonObject.getString(Constants.FacebookEmail),
String name = jsonObject.getString(Constants.FacebookName),
String firstName = jsonObject.getString(Constants.FacebookFirstName),
String lastName = jsonObject.getString(Constants.FacebookLastName),
String id = jsonObject.getString(Constants.FacebookID);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,first_name,last_name,birthday,email");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
DisplaySnackBar.display(getWindow().getDecorView().findViewById(android.R.id.content), "Sign In Cancel", true);
}
#Override
public void onError(FacebookException e) {
DisplaySnackBar.display(getWindow().getDecorView().findViewById(android.R.id.content), "Error", true);
}
});
}
Don't forget to add this dependency in your gradle build file
compile 'com.facebook.android:facebook-android-sdk:4.5.0'

post on facebook wall always show login page .. problem android

I'm using graph api from youtube , and i am facing some trouble .
I can send a msg to the wall , it works fine . The problem is that every time , it shows the login page and the user have to click at the ok button to send it. I'd like to send it without showing that page , it should only shows at the first time . I store the token using
shared preferences , but if i dont call the method facebook.autorize , which shows the login page , before trying to send the video , it does not work .
Am i doing it wrong ? thanks for any help .
My code :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.facebook_lay);
init();
acessToken = loadAccessToken();
Log.i("teste","Acesstoken depois do load : " + acessToken);
if(acessToken == null || acessToken.equals("")){
login();
}else{
Log.i("teste","Session valid com token salva ? " + mFacebook.isSessionValid());
sendVideo();
}
}
private void init(){
mFacebook = new Facebook(APP_ID);
videoUrl = getIntent().getExtras().getString("videoUrl");
preferences = this.getSharedPreferences(APPLICATION_PREFERENCES,
Context.MODE_PRIVATE);
}
private void login(){
mFacebook.authorize(this, new String[] {"publish_stream","offline_access"},new AuthorizeListener());
}
public void postOnWall(String msg) {
Log.i("teste", "Testing graph API wall post");
try {
Bundle parameters = new Bundle();
parameters.putString("message", AUTO_MSG);
parameters.putString("link", msg);
mFacebook.request("me/feed", parameters,
"POST");
} catch(Exception e) {
e.printStackTrace();
}
}
private void storeToken(String token){
Log.i("teste","storeToken: " + token);
Editor editor = preferences.edit();
editor.putString(ACESS_TOKEN, token);
editor.commit();
}
private String loadAccessToken() {
String token = preferences.getString(ACESS_TOKEN, null);
if (token != null && !token.equals("") ) {
return token;
} else {
return null;
}
}
private void sendVideo(){
dialog = ProgressDialog.show(FacebookView.this, "Sending","Enviando video ...");
new Thread(){
public void run() {
postOnWall(videoUrl);
dialog.dismiss();
finish();
};
}.start();
}
class AuthorizeListener implements DialogListener{
#Override
public void onCancel() {
Log.i("teste","Logou candelado!");
finish();
}
#Override
public void onComplete(Bundle values) {
Log.i("teste","Logou com sucesso!");
Log.i("teste", "AcessToken : " + mFacebook.getAccessToken());
Log.i("teste", "AcessToken expires : " + mFacebook.getAccessExpires());
Log.i("teste", "Session valid : " + mFacebook.isSessionValid());
storeToken(mFacebook.getAccessToken());
sendVideo();
}
#Override
public void onError(DialogError e) {
Log.i("teste","Erro ao logar: " + e.getMessage());
finish();
}
#Override
public void onFacebookError(FacebookError e) {
Log.i("teste","FacebookError ao logar: " + e.getMessage());
Log.i("teste","FacebookError ao logar Causa: " + e.getCause());
e.printStackTrace();
finish();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
mFacebook.authorizeCallback(requestCode, resultCode, data);
}
package com.greatup;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class MyGreatActivity extends Activity {
/** Called when the activity is first created. */
Facebook facebook = new Facebook("208086425868080");
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// facebook.authorize(this, new String[] { "email", "read_stream" },new DialogListener() {
//
// public void onComplete(Bundle values) {}
//
//
// public void onFacebookError(FacebookError error) {}
//
//
// public void onError(DialogError e) {}
//
// public void onCancel() {}
// });
facebook.dialog(this,"feed",
new DialogListener() {
#Override
public void onComplete(Bundle values) {}
#Override
public void onFacebookError(FacebookError error) {}
#Override
public void onError(DialogError e) {}
#Override
public void onCancel() {}
}
);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
facebook.authorizeCallback(requestCode, resultCode, data);
}
}
Already find the answer . Just have to set the token on the facebook object .
acessToken = loadAccessToken();
Log.i("teste","Acesstoken depois do load : " + acessToken);
if(acessToken == null || acessToken.equals("")){
login();
}else{
mFacebook.setAccessToken(acessToken);
Log.i("teste","Session valid com token salva ? " + mFacebook.isSessionValid());
sendVideo();
}

Categories