I am using google login for my android app, off lately i am getting Runtime exception reports with error "GoogleApiClient has an optional Plus.API and is not connected to Plus. Use GoogleApiClient.hasConnectedApi(Plus.API) to guard this call."
In activity result obtained from google sign in use this
if (mGoogleApiClient.hasConnectedApi(Plus.API)) {
Person person = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
if (person != null) {
//Take the required action
Log.i(TAG, "Display Name: " + person.getDisplayName());
Log.i(TAG, "Gender: " + person.getGender());
Log.i(TAG, "About Me: " + person.getAboutMe());
Log.i(TAG, "Birthday: " + person.getBirthday());
Log.i(TAG, "Current Location: " + person.getCurrentLocation());
Log.i(TAG, "Language: " + person.getLanguage());
} else {
Log.e(TAG, "Error!");
}
Related
I am working on an Android app that allows live chat and call functionality. I am new to WebRTC in android. I am trying to add multiple call functionality using WebRTC. I got success in connecting multiple P2P calls (Upto 6 users are easily gets connected using Mesh Topology.
Here are the steps that I am following:
A => B Call successful ==> Result: audio clear no problem on both the ends
A => C Adding New Caller C from A ==> Result: audio clear no problem on both the ends.
C => B in background C gives call to B and gets accepted on B's end => Result: audio clear no problem on all the ends.
Now, All 3 participants are connected and can communicate easily.
The issue is:
When any of the participants leaves the call, Any of the remaining participants are hearing Echo of their own voice.
All my call related setups are done using RingRTC. Please help if anyone has faced this issue.
I tried setting up Noisce Supressors, AcousticEchoCanceler and other options for each remaining audio sessions as below. But its not helping.
public void enable(int audioSession) {
Logging.d(TAG, "enable(audioSession=" + audioSession + ")");
assertTrue(aec == null);
assertTrue(agc == null);
assertTrue(ns == null);
// Add logging of supported effects but filter out "VoIP effects", i.e.,
// AEC, AEC and NS.
for (Descriptor d : AudioEffect.queryEffects()) {
if (effectTypeIsVoIP(d.type) || DEBUG) {
Logging.d(TAG, "name: " + d.name + ", "
+ "mode: " + d.connectMode + ", "
+ "implementor: " + d.implementor + ", "
+ "UUID: " + d.uuid);
}
}
if (isAcousticEchoCancelerSupported()) {
// Create an AcousticEchoCanceler and attach it to the AudioRecord on
// the specified audio session.
aec = AcousticEchoCanceler.create(audioSession);
if (aec != null) {
boolean enabled = aec.getEnabled();
boolean enable = shouldEnableAec && canUseAcousticEchoCanceler();
if (aec.setEnabled(enable) != AudioEffect.SUCCESS) {
Logging.e(TAG, "Failed to set the AcousticEchoCanceler state");
}
Logging.d(TAG, "AcousticEchoCanceler: was "
+ (enabled ? "enabled" : "disabled")
+ ", enable: " + enable + ", is now: "
+ (aec.getEnabled() ? "enabled" : "disabled"));
} else {
Logging.e(TAG, "Failed to create the AcousticEchoCanceler instance");
}
}
if (isAutomaticGainControlSupported()) {
// Create an AutomaticGainControl and attach it to the AudioRecord on
// the specified audio session.
agc = AutomaticGainControl.create(audioSession);
if (agc != null) {
boolean enabled = agc.getEnabled();
boolean enable = shouldEnableAgc && canUseAutomaticGainControl();
if (agc.setEnabled(enable) != AudioEffect.SUCCESS) {
Logging.e(TAG, "Failed to set the AutomaticGainControl state");
}
Logging.d(TAG, "AutomaticGainControl: was "
+ (enabled ? "enabled" : "disabled")
+ ", enable: " + enable + ", is now: "
+ (agc.getEnabled() ? "enabled" : "disabled"));
} else {
Logging.e(TAG, "Failed to create the AutomaticGainControl instance");
}
}
if (isNoiseSuppressorSupported()) {
// Create an NoiseSuppressor and attach it to the AudioRecord on the
// specified audio session.
ns = NoiseSuppressor.create(audioSession);
if (ns != null) {
boolean enabled = ns.getEnabled();
boolean enable = shouldEnableNs && canUseNoiseSuppressor();
if (ns.setEnabled(enable) != AudioEffect.SUCCESS) {
Logging.e(TAG, "Failed to set the NoiseSuppressor state");
}
Logging.d(TAG, "NoiseSuppressor: was "
+ (enabled ? "enabled" : "disabled")
+ ", enable: " + enable + ", is now: "
+ (ns.getEnabled() ? "enabled" : "disabled"));
} else {
Logging.e(TAG, "Failed to create the NoiseSuppressor instance");
}
}
}
We have created a Bluetooth application to test different BT profiles. We ran into an issue after an Android update (This is not Android version specific. Issue is seen on both Android 11 and 12. Issue is 100 % reproducible if the security patch date >= June 2022. Do find below the code which was working fine without any problems but now fails with the error, System.err: Caused by: java.lang.SecurityException: Need BLUETOOTH PRIVILEGED permission: Neither user 10243 nor current process has android.permission.BLUETOOTH_PRIVILEGED
This permission android.permission.BLUETOOTH_PRIVILEGED is only applicable for system apps. Seems like Android security update is now restricting usage of some hidden API's on user apps and would only be usable on system apps. There seems to be no other alternative public api for the below use. Can somebody help in this regard in case you had a similar use case and somehow resolved this?
public static void changeScanMode(String cmdSuffix, String strCmdName, BluetoothAdapter mBluetoothAdapter) {
String scanMode = cmdSuffix;
if (scanMode.equalsIgnoreCase("scan_connectable_on")) {
boolean result = setBluetoothScanMode(mBluetoothAdapter, SCAN_MODE_CONNECTABLE);
Log.v(TAG, "set scan mode connectable result " + result);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && ActivityCompat.checkSelfPermission(MainActivity.context, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
Log.e(TAG, "Permission not granted");
return;
}
if (mBluetoothAdapter.getScanMode() == SCAN_MODE_CONNECTABLE) {
Log.v(TAG, "[" + strCmdName.toUpperCase() + "] [PASS] scanMode: SCAN_MODE_CONNECTABLE");
} else {
Log.v(TAG, "[" + strCmdName.toUpperCase() + "] [FAIL] scanMode: SCAN_MODE_CONNECTABLE");
}
} else if (scanMode.equalsIgnoreCase("scan_connectable_discoverable_on")) {
boolean result = setBluetoothScanMode(mBluetoothAdapter, SCAN_MODE_CONNECTABLE_DISCOVERABLE);
Log.v(TAG, "set scan mode connectable discoverable result " + result);
if (mBluetoothAdapter.getScanMode() == SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Log.v(TAG, "[" + strCmdName.toUpperCase() + "] [PASS] scanMode: SCAN_MODE_CONNECTABLE_DISCOVERABLE");
} else {
Log.v(TAG, "[" + strCmdName.toUpperCase() + "] [FAIL] scanMode: SCAN_MODE_CONNECTABLE_DISCOVERABLE");
}
} else if (scanMode.equalsIgnoreCase("scan_mode_none")) {
boolean result = setBluetoothScanMode(mBluetoothAdapter, SCAN_MODE_NONE);
Log.v(TAG, "set scan mode none result " + result);
if (mBluetoothAdapter.getScanMode() == SCAN_MODE_NONE) {
Log.v(TAG, "[" + strCmdName.toUpperCase() + "] [PASS] scanMode: SCAN_MODE_NONE");
} else {
Log.v(TAG, "[" + strCmdName.toUpperCase() + "] [FAIL] scanMode: SCAN_MODE_NONE");
}
} else {
Log.v(TAG, "[" + strCmdName.toUpperCase() + "] [FAIL] scanMode: Enter Valid Scan Mode");
}
}
I know this question is everywhere in Stack-overflow and there are many answers to this question but I am unable to resolve it. I have tried many answers but still not able to solve the issue, I know that I am doing some silly mistake somewhere in my code, can anyone help me out finding the issue?
Here is My screen-shot for in-app products :-
Declared permissions inside Manifest :-
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />
Defining SKU as :-
public static final String SKU1 = "gas";
public static final String SKU2 = "infinite_gas";
Purchase Method :-
public void launchPurchaseFlow(Activity act, String sku, String itemType,
int requestCode, OnIabPurchaseFinishedListener listener,
String extraData) {
checkNotDisposed();
checkSetupDone("launchPurchaseFlow");
flagStartAsync("launchPurchaseFlow");
IabResult result;
if (itemType.equals(ITEM_TYPE_SUBS) && !mSubscriptionsSupported) {
IabResult r = new IabResult(IABHELPER_SUBSCRIPTIONS_NOT_AVAILABLE,
"Subscriptions are not available.");
flagEndAsync();
if (listener != null)
listener.onIabPurchaseFinished(r, null);
return;
}
try {
logDebug("Constructing buy intent for " + sku + ", item type: "
+ itemType);
Bundle buyIntentBundle = mService.getBuyIntent(3,
mContext.getPackageName(), sku, itemType, extraData);
int response = getResponseCodeFromBundle(buyIntentBundle);
if (response != BILLING_RESPONSE_RESULT_OK) {
logError("Unable to buy item, Error response: "
+ getResponseDesc(response));
flagEndAsync();
result = new IabResult(response, "Unable to buy item");
if (listener != null)
listener.onIabPurchaseFinished(result, null);
return;
}
PendingIntent pendingIntent = buyIntentBundle
.getParcelable(RESPONSE_BUY_INTENT);
logDebug("Launching buy intent for " + sku + ". Request code: "
+ requestCode);
mRequestCode = requestCode;
mPurchaseListener = listener;
mPurchasingItemType = itemType;
act.startIntentSenderForResult(pendingIntent.getIntentSender(),
requestCode, new Intent(), Integer.valueOf(0),
Integer.valueOf(0), Integer.valueOf(0));
} catch (SendIntentException e) {
logError("SendIntentException while launching purchase flow for sku "
+ sku);
e.printStackTrace();
flagEndAsync();
result = new IabResult(IABHELPER_SEND_INTENT_FAILED,
"Failed to send intent.");
if (listener != null)
listener.onIabPurchaseFinished(result, null);
} catch (RemoteException e) {
logError("RemoteException while launching purchase flow for sku "
+ sku);
e.printStackTrace();
flagEndAsync();
result = new IabResult(IABHELPER_REMOTE_EXCEPTION,
"Remote exception while starting purchase flow");
if (listener != null)
listener.onIabPurchaseFinished(result, null);
}
}
Bind Service Intent :-
Intent serviceIntent = new Intent(
"com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
if (!mContext.getPackageManager().queryIntentServices(serviceIntent, 0)
.isEmpty()) {
// service available to handle that Intent
mContext.bindService(serviceIntent, mServiceConn,
Context.BIND_AUTO_CREATE);
Consume Method :-
void consume(Purchase itemInfo) throws IabException {
checkNotDisposed();
checkSetupDone("consume");
if (!itemInfo.mItemType.equals(ITEM_TYPE_INAPP)) {
throw new IabException(IABHELPER_INVALID_CONSUMPTION,
"Items of type '" + itemInfo.mItemType
+ "' can't be consumed.");
}
try {
String token = itemInfo.getToken();
String sku = itemInfo.getSku();
if (token == null || token.equals("")) {
logError("Can't consume " + sku + ". No token.");
throw new IabException(IABHELPER_MISSING_TOKEN,
"PurchaseInfo is missing token for sku: " + sku + " "
+ itemInfo);
}
logDebug("Consuming sku: " + sku + ", token: " + token);
int response = mService.consumePurchase(3,
mContext.getPackageName(), token);
if (response == BILLING_RESPONSE_RESULT_OK) {
logDebug("Successfully consumed sku: " + sku);
} else {
logDebug("Error consuming consuming sku " + sku + ". "
+ getResponseDesc(response));
throw new IabException(response, "Error consuming sku " + sku);
}
} catch (RemoteException e) {
throw new IabException(IABHELPER_REMOTE_EXCEPTION,
"Remote exception while consuming. PurchaseInfo: "
+ itemInfo, e);
}
}
Error while purchasing :-
Note :- The Application in Alpha testing phase is published.
Do i need to Approve my tester account from somewhere ?
Here are the whole process i do :-
Uploaded the signed apk with release certificated to developer
console.
I have published my apk to alpha channel.
I have listed my product Ids to developer console.
I have activated my product Ids and on developer console it is marked as Active.
I have listed the test account in developer console.
I have installed the same apk that I uploaded to developer console to my deveice.
The device is logged in with the test account not the developer account.
The Id that I use in my app is same as I had listed on console as per logcat message.
Any help will be greatly appreciated
Thanks in advance.
yes , i solved the problem , i was missing with this last and very important step :-
Open opt-in url with test account and click on "Become a tester"
I'm trying to send file from Android host to Samsung Gear device using Samsung Mobile SDK no matter how had I try, always get FILE_IO error.
I was trying all available permissions (on both sides).
Could anyone send me any hint?
Android side:
String filename = "file:///storage/emulated/0/Download/TestRecipe2-25.zip";
if (mGuruAgentService != null) mGuruAgentService.sendFile(filename);
public int sendFile(String fileName) {
if (mFileTransfer == null)
registerForFileTransfer();
if (mFileTransfer != null) {
try {
Log.i(TAG, "Sending file " + fileName);
tx = mFileTransfer.send(mPeerAgent, fileName);
return tx;
} catch (Exception e)
{
Log.i(TAG, "Cannot send file" + e.getMessage());
}
}
return 0;
}
Tizen side:
function fileReceiveInt() {
var newFilePath = "downloads/file.zip";
var receivefilecallback =
{
onreceive: function(transferId, fileName)
{
console.log("Incoming file transfer request form the remote peer agent. transferId: " + transferId + " file name : " + fileName);
try {
gFileTransfer.receiveFile(transferId, newFilePath);
} catch(e) {
console.log("Error Exception, error name : " + e.name + ", error message : " + e.message);
}
},
onprogress: function(transferId, progress)
{
console.log("onprogress transferId: " + transferId + ", progress : " + progress);
},
oncomplete: function(transferId, localPath)
{
console.log("File transfer complete. transferId: " + transferId);
},
onerror: function(errorCode, transferId)
{
console.log("FileReceiveError transferId: " + transferId + " code : " + errorCode);
}
}
try {
console.log('setting recieve interface');
gFileTransfer = SAAgent.getSAFileTransfer();
gFileTransfer.setFileReceiveListener(receivefilecallback);
} catch (err) {
console.log('getSAFileTransfer exception <' + err.name + '> : ' + err.message);
}
}
I will always get onError in tizen with FILE_IO error :(
I was testing gFileTransfer.receiveFile(transferId, ""); for default path, and File:///opt/usr/media/Downloads...
My tizen privileges:
<tizen:privilege name="http://tizen.org/privilege/content.read"/>
<tizen:privilege name="http://developer.samsung.com/privilege/accessoryprotocol"/>
<tizen:privilege name="http://tizen.org/privilege/content.write"/>
<tizen:privilege name="http://tizen.org/privilege/filesystem.read"/>
<tizen:privilege name="http://tizen.org/privilege/filesystem.write"/>
<tizen:privilege name="http://tizen.org/privilege/unlimitedstorage"/>
Thanks in advance for any help.
Change both filepaths and it should work.
Change Android's side to:
String filename = Environment.getExternalStorageDirectory() + "/Download/TestRecipe2-25.zip";
Change Tizen's side to:
var newFilePath = "file:///opt/usr/media/Downloads/file.zip";
I am using facebook plugin to login and logout a user, which are working fine. The problem is when I request for the logged in user details using the function FB.api('/me'), it always gives the following error:
{"message":"An active access token must be used to query information about the current user.","type":"OAuthException","code":2500}
I used the debug mode to check PluginResult(pr) and JSONObject of the response. JSONObject contains the user information, which I required, I dont get where I am doing wrong.
Plz help......
MY CODE:
function login() {
FB.login(function(response) {
if (response.session) {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + JSON.stringify(response) + '.');
});
} else {
console.log('User cancelled login or did not fully authorize.');
}
},{scope: 'email,user_likes'});
}
function logout() {
FB.logout(function(response) {
console.log(localStorage.getItem("user_fb_log_status"));
localStorage.setItem("user_fb_log_status","LOGGED_OUT");
alert('logged out');
});
}
The above code is working fine to login and logout the user. Below is the code i used to get the user details,
function me() {
FB.api('/me', { fields: 'id, name, picture' }, function(response) {
if (response.error) {
alert(JSON.stringify(response.error));
} else {
var data = document.getElementById('data');
fdata=response.data;
console.log("fdata: "+fdata);
response.data.forEach(function(item) {
var d = document.createElement('div');
d.innerHTML = "<img src="+item.picture+"/>"+item.name;
data.appendChild(d);
});
}
});
}
You need access token to retrieve more details than basic user information. Check that whether you have correct access token in Debug Tool to and ensure that you have all require permissions set permission.
Problem solved after changing the "session" in 'getResponse' method in ConnectPlugin to "authResponse"
FB.api method is working fine for me to get the user details and post a feed to the facebook after I change the following method in ConnectPlugin.java as following.
public JSONObject getResponse() {
String response = "{" + "\"status\": \""
+ (facebook.isSessionValid() ? "connected" : "unknown") + "\","
+
// "\"session\": {" + "\"access_token\": \""
// + facebook.getAccessToken() + "\"," + "\"expires\": \""
// + facebook.getAccessExpires() + "\","
// + "\"session_key\": true," + "\"sig\": \"...\","
// + "\"uid\": \"" + this.userId + "\"" +
"\"authResponse\": {" +
"\"accessToken\": \"" + facebook.getAccessToken() + "\"," +
"\"expiresIn\": \"" + facebook.getAccessExpires() + "\"," +
"\"session_key\": true," +
"\"sig\": \"...\"," +
"\"userId\": \"" + this.userId + "\"" +
"}" + "}";
try {
return new JSONObject(response);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new JSONObject();
}