How to fix java.lang.SecurityException: This PhoneAccountHandle is not enabled for this user? - android-connectionservice

I had the below given code working for me to make a self managed connecion service. But this has stopped working with this error:
java.lang.SecurityException: This PhoneAccountHandle is not enabled for this user!
Code:
class CallManager(context: Context) {
val telecomManager: TelecomManager
var phoneAccountHandle: PhoneAccountHandle
var context: Context
init {
telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
this.context = context
val componentName = ComponentName(this.context, ConnService::class.java)
phoneAccountHandle = PhoneAccountHandle(componentName,"com.darkhorse.videocalltest")
}
fun register(){
val phoneAccount = PhoneAccount.builder(phoneAccountHandle,"com.darkhorse.videocalltest")
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER).build()
telecomManager.registerPhoneAccount(phoneAccount)
}
fun incomingCall(caller: String?){
val callInfo = Bundle()
callInfo.putString("from", caller)
telecomManager.addNewIncomingCall(phoneAccountHandle,callInfo)
Log.i("incomingCall", "incomingCall")
}
}
I am sure the same code was working fine earlier.
This question doesn't help.

registerPhoneAccount
PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle(new ComponentName(getApplicationContext().getPackageName(),MyConnectionService.class.getName()),"TestApp");
TelecomManager telecomManager = (TelecomManager) getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
PhoneAccount.Builder builder = new PhoneAccount.Builder(phoneAccountHandle, "TestApp");
builder.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER);
PhoneAccount phoneAccount = builder.build();
telecomManager.registerPhoneAccount(phoneAccount);
Enable PhoneAccount
Intent intent=new Intent();
intent.setClassName("com.android.server.telecom","com.android.server.telecom.settings.EnableAccountPreferenceActivity");
startActivity(intent);

Related

Unable to access DynamoDb Locally from Kotlin

First I want to say I am pretty new to Kotlin and DynamoDB. I am writing a sample program in Kotlin to play with DynamoDb. I am following the steps in this link: https://docs.aws.amazon.com/sdk-for-kotlin/latest/developer-guide/examples-dynamodb-tables.html
First I instantiate a client object for making requests to DynamoDB
val dynamoDbClient = DynamoDbClient { region = "us-east-1" }
Then I run the code below to create a new table.
suspend fun createNewTable(ddb: DynamoDbClient, newTableName: String, key: String): String {
val attDef = AttributeDefinition {
attributeName = key
attributeType = ScalarAttributeType.S
}
val keySchemaVal = KeySchemaElement {
attributeName = key
keyType = KeyType.Hash
}
val provisionedVal = ProvisionedThroughput {
readCapacityUnits = 10
writeCapacityUnits = 10
}
val request = CreateTableRequest {
attributeDefinitions = listOf(attDef)
keySchema = listOf(keySchemaVal)
provisionedThroughput = provisionedVal
tableName = newTableName
}
try {
val response = ddb.createTable(request)
val tableActive = false
// Wait until the table is in Active state.
while (!tableActive) {
val tableStatus = checkTableStatus(ddb, newTableName)
if (tableStatus.equals("ACTIVE"))
break
delay(500)
}
return response.tableDescription?.tableArn.toString()
} catch (e: DynamoDbException) {
println("ERROR (DynamoDbException): " + e.message)
} catch (e: UnknownServiceErrorException) {
println("ERROR (UnknownServiceErrorException): " + e.message)
} finally {
ddb.close()
}
return ""
}
I can see the table created on my AWS account. However I want to modify my DynamoDbClient to execute the table creation on a local instance of the DynamoDB. I followed the instructions from AWS pages and I installed DynamoDB locally.
Here is how I am running it locally:
c:\code\dynamodb_local_latest>java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb
Initializing DynamoDB Local with the following configuration:
Port: 8000
InMemory: false
DbPath: null
SharedDb: true
shouldDelayTransientStatuses: false
CorsParams: *
I am able to access the local DynamoDB instance from the aws cli tool.
In order to try accessing the local instance of DynamoDB from the Kotlin code, I changed DynamoDbClient from this:
val dynamoDbClient = DynamoDbClient { region = "us-east-1" }
to this:
val endpoint = aws.sdk.kotlin.runtime.endpoint.Endpoint( "localhost",
"http",
port=8000,
false,
null,
"us-west-1")
val myEndpointResolver = StaticEndpointResolver(endpoint)
val dynamoDbClient = DynamoDbClient {endpointResolver = myEndpointResolver; region ="us-west-1" }
However I get the following error:
Exception in thread "DefaultDispatcher-worker-1" software.amazon.awssdk.crt.http.HttpException: socket connection refused.
at software.amazon.awssdk.crt.http.HttpClientConnection.onConnectionAcquired(HttpClientConnection.java:85)
What is the proper way to resolve that?
Thanks!
You can specify the EndPointResolver for the DynamoDbClient with the address of your DynamoDb local instance.
For example:
class LocalHostDynamoDb: AwsEndpointResolver {
override suspend fun resolve(service: String, region: String): AwsEndpoint
= AwsEndpoint("http://localhost:8000")
}
class MyClient {
...
val dynamoDbClient = DynamoDbClient {
region = awsRegion
endpointResolver = LocalHostDynamoDb()
}
...

asp.net core api get null value from kotlin

I created an API with ASP.net Core that works with postman well. But when I pass data with Kotlin and Retrofit, API get null values. All data send to server via Kotlin fine.
All models in Kotlin and in ASP.net Core are same.
This is my Retrofit class:
class ApiClient {
companion object{
var retrofit:Retrofit? = null
var baseUrl = "http://10.0.2.2:5000/api/"
fun getClient():Retrofit{
if(retrofit == null){
var okHttpClient = OkHttpClient().newBuilder()
.addInterceptor {
var oldRequest = it.request()
var newRequestBuilder = oldRequest.newBuilder()
if (Utils.myToken != null) {
newRequestBuilder.addHeader("token", Utils.myToken!!)
}
newRequestBuilder.addHeader("Accept", "application/json")
newRequestBuilder.method(oldRequest.method, oldRequest.body)
return#addInterceptor it.proceed(newRequestBuilder.build())
}.build()
retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build()
}
return retrofit!!
}
}
}
This is Retrofit Interface Code:
#FormUrlEncoded
#POST("authentication/login")
fun login(
#Field("username") username:String,
#Field("password") password:String
):Call<Result>
This my Kotlin code:
loginViewModel.login(username,password).observe(viewLifecycleOwner,{
if(it.Status < 0){
Toast.makeText(context,it.Message,Toast.LENGTH_SHORT).show()
}else{
val manager = activity?.supportFragmentManager
loginViewModel.setToken(it.Message)
loginViewModel.setRoleId(it.Status)
Utils.createAnimation(activity?.findViewById(R.id.frm_mainActivity_mainLayout),Techniques.SlideInRight,700,0)
Utils.createFragment(manager!!,HomeFragment(),false)
}
})
This is ASP.net Core API code:
[HttpPost("login")]
public async Task<ActionResult<Result>> Login(string username,string password){
var user = await _repository.Login(username,password);
Result result = new Result();
if(user == null)
{
result.Status = -1;
result.Message = "نام کاربری یا کلمه عبور اشتباه است";
return NotFound(result);
}
else
{
result.Status = user.RoleId;
result.Message = user.Token;
return Ok(result);
}
}
So why does API get null values?
First create a DTO as login then pass that to Login function in ASP.net Core instead of username and password like this:
public class Login
{
public string Username { get; set; }
public string Password { get; set; }
}
The login function in controller changes like this:
[HttpPost("login")]
public async Task<ActionResult<Result>> Login(Login login){
var user = await _repository.Login(login.Username,login.Password);
Result result = new Result();
if(user == null)
{
result.Status = -1;
result.Message = "نام کاربری یا کلمه عبور اشتباه است";
return NotFound(result);
}
else
{
result.Status = user.RoleId;
result.Message = user.Token;
return Ok(result);
}
}
Then in Kotlin should create a model like the Login DTO in ASP.net Core
class Login(var username:String,var password:String)
Now should change Retrofit interface and use #Body instead of #Field like this:
#POST("authentication/login")
fun login(#Body login: Login):Call<Result>
So should change all methods that call the login method, because now this method takes login model instead of username and password

Get value from EditText

I want to log in from firebase.
But I can't get the value from EditText.
MyCode
var name = findViewById<EditText>(R.id.signName)
var email = findViewById<EditText>(R.id.signEmail)
var password = findViewById<EditText>(R.id.signPass)
val mEmail = email.text.toString()
val mPass = password.text.toString()
Log.d("eee", "data $mEmail $mPass")
btnOK.setOnClickListener {
var auth = FirebaseAuth.getInstance()
auth.createUserWithEmailAndPassword(mEmail, mPass)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
Log.d("sign", "create:success")
val intent = Intent(applicationContext, MainLoginActivity::class.java)
startActivity(intent)
} else {
Log.w("sign", "create:failure", task.exception)
Toast.makeText(this, "Authentication failed.", Toast.LENGTH_SHORT).show()
name.setText("")
email.setText("")
password.setText("")
name.requestFocus()
}
}
}
Nothing appeared in the log.
Log is : 2020-05-17 *** D/eee: data
Error is : java.lang.IllegalArgumentException: Given String is empty or null
Try placing these two lines inside the onClickListener.
mEmail = email.text.toString()
mPass = password.text.toString()

Signalr .net core 2.2 - mesages going to non connected groups

I am using .net core 2.2 with SignalR version 1.1.0. When I test the app, messages are being received by member who are NOT in the group. My groups are being dynamically created at run time based on relevant criteria, as in : var TheHub = CurrUser.Hubname; I cannot work out why group members who are NOT in the group are also receiving the messages. I am sending to GROUP and not ALL.
Please see code. Any help greatly appreciated, I am ready to pull my hair out.
My hub class
public class Chathub : Microsoft.AspNetCore.SignalR.Hub
{
public override async Task OnConnectedAsync()
{
var TheHub = CurrUser.Hubname;
await Groups.AddToGroupAsync(Context.ConnectionId, TheHub.ToString());
await base.OnConnectedAsync();
}
public Task SendMessageGroup(string user, string message)
{
var TheHub = CurrUser.Hubname;
return Clients.Group(TheHub.ToString()).SendAsync("ReceiveMessage", user, message);
}
}
My Javascript
"use strict";
document.getElementById("sendgroupButton").addEventListener("click", function (event) {
var user = document.getElementById("userInput").value;
var message = document.getElementById("messageInput").value;
connection.invoke("SendMessageGroup", user, message).catch(function (err) {
return console.error(err.toString());
});
event.preventDefault();
playAudio();
});
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
document.getElementById("sendgroupButton").disabled = true;
connection.on("ReceiveMessage", function (user, message) {
var msg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
var encodedMsg = user + " says " + msg;
var li = document.createElement("li");
li.textContent = encodedMsg;
document.getElementById("messagesList").appendChild(li);
});
connection.start().then(function () {
document.getElementById("sendgroupButton").disabled = false;
}).catch(function (err) {
return console.error(err.toString());
});
This is how I get the current value for curruser.hubname, please see below.
#inject SignInManager<ApplicationUser> SignInManager
#inject UserManager<ApplicationUser> UserManager
#if (SignInManager.IsSignedIn(User))
{
CurrUser.CurrentUsertId = UserManager.GetUserId(User);
var ctx = new WebookContext();
var LoggedInGuestHouseName = (from Ghouse in ctx.Guesthouse
where Ghouse.UserId == CurrUser.CurrentUsertId
select Ghouse).SingleOrDefault();
//check to see if guesthouse details have been completed, if not skip this next line of code.
if( LoggedInGuestHouseName != null)
{
CurrUser.GuestHouseName = LoggedInGuestHouseName.GuestHouseName;
// add the hub to current user
CurrUser.HubId = (int) LoggedInGuestHouseName.HubId;
var Ghname = LoggedInGuestHouseName.GuestHouseName;
var GhUserEmailaddress = LoggedInGuestHouseName.Emailaddress;
var GhHuId = LoggedInGuestHouseName.HubId;
CurrUser.GuestHouseName = Ghname;
CurrUser.GuestHouseEmailaddress = GhUserEmailaddress;
var q = (from gh in ctx.Hub
where gh.HubId == GhHuId
select gh).SingleOrDefault();
var myhubname = q.HubName;
CurrUser.Hubname = myhubname;
};
}
Looks like SignalR core is not for the feint hearted. Until a authoritative book comes out, one is really walking blind. I have researched this topic blue, but alas have now given up on SignalR for now.

Smack: SSL/TLS required by server but disabled in client

I am developing one to one chat , but i am facing the issue SSL/TLS required by server but disabled in client ,don't know what i am doing wrong , please help me out to figure out the mistake
My Service Class:
class ChatService:Service() {
var text = ""
var chat:Chat?=null
companion object {
private val DOMAIN = "localhost"
private val USERNAME = "admin#localhost"
private val PASSWORD = "localhost"
var cm: ConnectivityManager? = null
var xmpp: MyXMPP? = null
var ServerchatCreated = false
fun isNetworkConnected(): Boolean {
return cm!!.getActiveNetworkInfo() != null
}
}
override fun onCreate() {
super.onCreate()
cm= getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
xmpp = MyXMPP.getInstance(this, DOMAIN, USERNAME, PASSWORD);
xmpp!!.connect("onCreate");
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return START_NOT_STICKY
}
override fun onBind(intent: Intent?): IBinder? {
return LocalBinder<ChatService>(this)
}
override fun onDestroy() {
super.onDestroy()
xmpp!!.disconnect();
}
}
My XMPP Class For the connection:
companion object {
fun getInstance(context: ChatService, server: String, user: String, pass: String): MyXMPP {
if (instance == null) {
instance = MyXMPP(context, server, user, pass)
instanceCreated = true
}
return instance!!
}
}
constructor(context: ChatService, serverAdress: String, logiUser: String, passwordser: String) {
this.serverAddress = serverAdress
this.loginUser = logiUser
this.passwordUser = passwordser
this.context = context
initialiseConnection()
}
private fun initialiseConnection() {
val serviceName = JidCreate.domainBareFrom("localhost")
val config = XMPPTCPConnectionConfiguration.builder()
config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
config.setServiceName(serviceName)
config.setHostAddress(InetAddress.getByName("192.168.0.101"))//my ip address
config.setPort(5222)
config.setXmppDomain(serviceName)
config.setDebuggerEnabled(true)
//System.setProperty("smack.debugEnabled", "true")
XMPPTCPConnection.setUseStreamManagementResumptiodDefault(true)
XMPPTCPConnection.setUseStreamManagementDefault(true)
connection = XMPPTCPConnection(config.build())
val connectionListener = XMPPConnectionListener()
connection!!.addConnectionListener(connectionListener)
}
Inner class to MyXMPP class:
inner class XMPPConnectionListener : ConnectionListener {
override fun connected(connection: XMPPConnection) {
Log.d("xmpp", "Connected!")
connected = true
if (!connection.isAuthenticated) {
login()
}
}
override fun connectionClosed() {
if (isToasted)
Handler(Looper.getMainLooper()).post(Runnable {
// TODO Auto-generated method stub
Toast.makeText(
context, "ConnectionCLosed!",
Toast.LENGTH_SHORT
).show()
})
Log.d("xmpp", "ConnectionCLosed!")
connected = false
chat_created = false
loggedin = false
}
override fun connectionClosedOnError(arg0: Exception) {
if (isToasted)
Handler(Looper.getMainLooper()).post(Runnable {
Toast.makeText(
context, "ConnectionClosedOn Error!!",
Toast.LENGTH_SHORT
).show()
})
Log.d("xmpp", "ConnectionClosedOn Error!")
connected = false
chat_created = false
loggedin = false
}
Login to ejabber server :
fun login() {
try {
connection?.login(loginUser, passwordUser)
Log.i("LOGIN", "Yey! We're connected to the Xmpp server!")
} catch (e: XMPPException) {
e.printStackTrace()
} catch (e: SmackException) {
e.printStackTrace()
} catch (e: IOException) {
e.printStackTrace()
} catch (e: Exception) {
}
}
Logcat :
D/SMACK: RECV (0): <?xml version='1.0'?><stream:stream id='1777473137180053616' version='1.0' xml:lang='en' xmlns:stream='http://etherx.jabber.org/streams' from='localhost' xmlns='jabber:client'>
2019-04-29 13:25:40.247 30893-30976/shop.com.letsshop D/SMACK: RECV (0): <stream:features><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'><required/></starttls></stream:features>
2019-04-29 13:25:40.249 30893-30974/shop.com.letsshop E/(onCreate): SMACKException: SSL/TLS required by server but disabled in client
2019-04-29 13:25:40.251 30893-30976/shop.com.letsshop W/AbstractXMPPConnection: Connection XMPPTCPConnection[not-authenticated] (0) closed with error
org.jivesoftware.smack.SmackException$SecurityRequiredByServerException: SSL/TLS required by server but disabled in client
at org.jivesoftware.smack.tcp.XMPPTCPConnection.afterFeaturesReceived(XMPPTCPConnection.java:928)
at org.jivesoftware.smack.AbstractXMPPConnection.parseFeatures(AbstractXMPPConnection.java:1446)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$1100(XMPPTCPConnection.java:149)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1048)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:980)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:996)
at java.lang.Thread.run(Thread.java:764)
2019-04-29 13:25:40.252 30893-30976/shop.com.letsshop D/xmpp: ConnectionClosedOn Error!
After lot's of struggle i found the solution :)
MyXmpp Class :
val serviceName = JidCreate.domainBareFrom("localhost")// if user is register as admin#localhost ,you should have to take only string after "#" i.e localhost
val config = XMPPTCPConnectionConfiguration.builder()
config.setSecurityMode(ConnectionConfiguration.SecurityMode.required);
config.setXmppDomain(serviceName);
config.setHostAddress( InetAddress.getByName("192.168.0.101"))// your server ip address or for local host ,pc ip address
config.setPort(5222)
config.setDebuggerEnabled(true)
val sslContext = getSSLContext()// setting ssl
config.setCustomSSLContext(sslContext)
SASLAuthentication.blacklistSASLMechanism("SCRAM-SHA-1")
SASLAuthentication.blacklistSASLMechanism("DIGEST-MD5")
SASLAuthentication.unBlacklistSASLMechanism("PLAIN")
XMPPTCPConnection.setUseStreamManagementResumptiodDefault(true)
XMPPTCPConnection.setUseStreamManagementDefault(true)
connection = XMPPTCPConnection(config.build())
connection?.login("admin", "localhost")//ejabber server login id .if you have admin#localhost then take only admin as a username . password i am having as localhost.
Enabling the SSL :
#Throws(IOException::class,
CertificateException::class, NoSuchAlgorithmException::class, KeyStoreException::class, KeyManagementException::class)
private fun getSSLContext():SSLContext{
var cf: CertificateFactory? =null
try {
cf = CertificateFactory.getInstance("X.509");
} catch (e:CertificateException) {
Log.d("ca", "ca=" + e.message);
}
var input = context.getResources().openRawResource(R.raw.my_keystore); // R.raw.chain is CA Root Certificate added in RAW resources folder
var caInput = BufferedInputStream(input);
var ca:Certificate?=null
try {
ca = cf!!.generateCertificate(caInput)
// Log.d("ca", "ca=" + ((X509Certificate) ca).getSubjectDN())
}
catch (e:Exception){
Log.e("ca", e.message);
}
finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
var keyStoreType = KeyStore.getDefaultType();
var keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
var tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
var tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
var sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
return sslContext;
}
Here i got stuck : How to find the my_keystore . Then I found in server.pem file in ejabbered there you find private key that key i have to paste in the client side(Android Studio->res->raw(folder)->my_keystore(make a empty file like this)) i.e in my_keystore file .Here is the full path to reach server.pem . /opt/ejabberd/conf
in your initialiseConnection() method
change
config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
to
config.setSecurityMode(ConnectionConfiguration.SecurityMode.ifpossible)
solve this issue for me