Here is my registration code:
protected void initializeManagerOpen(){
consoleWrite("initializeOpen");
if(mSipManager==null) {
return;
}
SipProfile.Builder builder;
try {
builder = new SipProfile.Builder("13", "10.0.0.4");
builder.setPassword("13");
builder.setPort(5062);
builder.setProtocol("UDP");
mSipProfile = builder.build();
try {
Intent intent = new Intent();
intent.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, Intent.FILL_IN_DATA);
mSipManager.open(mSipProfile, pendingIntent, null);
mSipManager.setRegistrationListener(mSipProfile.getUriString(), new SipRegistrationListener() {
public void onRegistering(String localProfileUri) {
mNotificationTask.endNotification();
mNotificationTask.createNotification(R.drawable.ic_stat_connecting,"Test","Connecting");
consoleWrite("Registering with SIP Server...");
}
public void onRegistrationDone(String localProfileUri, long expiryTime){
mNotificationTask.endNotification();
mNotificationTask.createNotification(R.drawable.ic_stat_connected,"Test","Connected");
consoleWrite("Ready");
}
public void onRegistrationFailed(String localProfileUri, int errorCode, String errorMessage){
mNotificationTask.endNotification();
mNotificationTask.createNotification(R.drawable.ic_stat_disconnected,"Test","Failed to connect:"+errorCode);
consoleWrite("Registration failed. Please check settings.");
consoleWrite(""+errorCode);
consoleWrite(errorMessage);
}
});
} catch (SipException e) {
e.printStackTrace();
}
} catch (ParseException e) {
e.printStackTrace();
}
}
Though sometimes it registered successfully, most time I got a error code -9:
Registration failed. Please check settings.
-9
0
I found this description on reference site:
public static final int IN_PROGRESS
The client is in a transaction and cannot initiate a new one.
Constant Value: -9 (0xfffffff7)
What does it means exactly? I don't have any other SIP application running on my phone.
PS. First time when i am trying to connect, it is working. But second time it returns -9. Maybe i not close connection correctly? I think i have problem because i am trying to close connection but it is not closing...
public void closeLocalProfile() {
if(mSipManager==null){
return;
}
try{
if(mSipProfile!=null){
mSipManager.close(mSipProfile.getUriString());
consoleWrite("mSipManager Closed - "+mSipProfile.getUriString());
}
}catch(Exception e){
consoleWrite("Failed to close local profile. - "+e);
}
}
Delete all SIP account from Call Parameter and retry :
Call App->Parameter->Call account internet
Delete all account
PS: Sorry for the name menu, my phone isn't in english
I've faced the same issue and zicos22's comment helped me to solve it. The problem starts because of unclosed SipProfiles, so you need to run closeLocalProfile() inside onPause() method (it does not work when called inside onDestroy()). Actually, i think i have to run this sip stuff in separate thread, but for now i'm just closing profile in onPause. On my android phone with ZenUI i'am able to close currently opened sip profiles manually in Settings -> Call Settings -> Phone Account Settings -> SIP accounts.
Related
I have been stuck with one problem. I need some people which check a part of my code and help me with problem and critize my code (I write code but I haven't people which can say this is wrong or something in this pattern)
Generally.
My service get message from bluetooth (HC-05) and I can see values in Log.d, in service.
A part code of my service which get message.
private class ConnectedThread extends Thread{
private final BluetoothSocket bluetoothSocket;
private final InputStream inputStream;
private final OutputStream outputStream;
public ConnectedThread(BluetoothSocket socket){
Log.d(TAG,"ConnectedThread: Starting");
bluetoothSocket=socket;
InputStream tmpInput = null;
OutputStream tmpOutput = null;
try{
tmpInput = bluetoothSocket.getInputStream();
tmpOutput = bluetoothSocket.getOutputStream();
}catch (IOException e){
e.printStackTrace();
active=false;
}
inputStream=tmpInput;
outputStream=tmpOutput;
}
#Override
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while(active){
try {
bytes = inputStream.read(buffer);
final String comingMsg = new String(buffer,0,bytes);
Log.d(TAG,"InputStream: " + comingMsg);
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Message message = new Message();
message.obj = comingMsg;
message.what = 1; // I need it to prevent NullObjReference
Log.d(TAG,"Handler run(): " + message.obj);
mHandler.sendMessage(message);
}
});
}catch (IOException e){
Log.e(TAG,"Write: Error reading input." + e.getMessage());
active=false;
break;
}
}
}
...some code is hidden because it is diploma thesis
}
The problem is get message every time from this service to another activity where all is happen.
I tried a lot of things (with Threads,Looper,runOnUiThread, handleMessage and callback), checked a lot of posts in stackoverflow and I tried to combine with my project but all time I had nullobjectreference (for that i tried to use msg.what to check) , black screen when tried to move to my home activity (it is main) and update my textView or typical crash app.
Now I want only to get message from service to textview. When everything starts working fine, I want to parse string (for example 3 first chars) and send message to one of six textviews.
A part of codes from onCreate before method runThread() is started:
Log.d(TAG,"Check intent - result");
if(getIntent().getIntExtra("result",0)==RESULT_OK){
mDevice = getIntent().getExtras().getParcelable("bonded device");
startConnection(mDevice,MY_UUID);
Log.d(TAG,"Check is active service ");
checkIfActive();;
}
Log.d(TAG,"Check intent - connect_to_paired");
if(getIntent().getIntExtra("connect_to_paired",0)==RESULT_OK){
mDevice = getIntent().getExtras().getParcelable("bonded_paired_device");
startConnection(mDevice,MY_UUID);
Log.d(TAG,"Check is active service ");
checkIfActive();
}
public void checkIfActive(){
Log.d(TAG,"CheckIfActive: Started");
while(myBluetoothService.active!=true) {
Log.d(TAG,"CheckIfActive() active is "+ myBluetoothService.active);
if (myBluetoothService.active) {
Log.d(TAG, "CheckIfActive: Running method runOnUiThread - myBluetoothService.active is "+myBluetoothService.active);
runThread();
}
}
}
Method runThread() which should work everytime after connected with bluetooth device:
public void runThread(){
//I used there Thread but when connection was fail,
// method created multiply threads when I tried to connect next time
runOnUiThread(new Runnable() {
#Override
public void run() {
handler = new Handler(Looper.getMainLooper()){
#Override
public void handleMessage(Message msg) {
while (true) {
switch (msg.what) {
//when is one, service has messages to send
case 1:
String message = myBluetoothService.mHandler.obtainMessage().toString();
rearLeft.setText(message);
break;
default:
super.handleMessage(msg);
}
}
}
};
}
});
}
UPDATE:
Is it good idea ? Maybe I can put JSON Object to service to send message and in the HomeActivity, I can try get values from JSON. Is it fast ? I send a lot of data, because bluetooth receive data of distance from 4 ultrasound sensors in 4 times in lasts until few milliseconds, everytime.
Here is screen how sees my data in service when I have debug logs.
Next idea, but still nothing:
HomeActivity (my main)
public void runThread(){
runOnUiThread(new Runnable() {
#Override
public void run() {
//Looper.prepare();
new Handler() {
#Override
public void handleMessage(Message msg) {
rearLeft.setText(msg.obj.toString());
}
};
//Looper.loop();
//Log.d(TAG, myBluetoothService.mHandler.getLooper().toString());
//rearLeft.setText(myBluetoothService.mHandler.getLooper().toString());
}
});
}
Service which should send data from bluetooth to UI Thread is the same (Check first code).
Screen from HomeActivity where you can see 6 text views. Now I want put all text to one view which will be refresh by get next message.
Ok this post a bit help me to solve problem:
Sending a simple message from Service to Activity
Maybe this link could help another people.
Thanks for help, now understand why i should use broadcast receiver to do this.
i have a class(location2.java) that finds location for me,I use this code in my class :
What is the simplest and most robust way to get the user's current location on Android?
and I have a service that override that abstract "locationResult";Now i want my service after running its codes,service doesn't finish and stay alive for receiving location from location2.java.
appreciating any help for this.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Location2.LocationResult locate = new Location2.LocationResult() {
#Override
public void gotLocation(Location location1, Boolean Gps, Boolean Net) {
if (location1 != null) {
Log.e("Loc", String.valueOf(location1.getLatitude()));
}
try {
//this is a method that i want to be run after receiving location from location2.java
json_maker(location1, speed_computation(location1), Gps, Net);
} catch (JSONException e) {
e.printStackTrace();
}
}
};
Location2 location = new Location2();
location.getLocation(context, locate);
return Service.START_FLAG_REDELIVERY;
}
The most successful way is to use return START_STICKY.
"and if service wants to restart, multiple constants for example START_STICKY can be used.doesn't it?" - Yes, we can use.
START_STICKY
Constant to return from onStartCommand(Intent, int, int) if this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then leave it in the started state but don't retain this delivered intent. Developer guide: Android
hypothesis.getHypstr() is always one value, even after I change the keyword!
I am using pocketsphinx to do speech recognition, and I let the user change what to listen for. This value is stored in my shared preferences. My problem is that hypothesis.getHypstr() is only called when the previous keyword is spoken.
For example:
If it is set to default keyword (oranges and rainbows), then the recognition works fine. But, if the user changes it to "hello computer" then the onPartialResult method still only gets called when the user says hello, and hypothesis.getHypstr() is still oranges and rainbows.
onCreate:
try {
Assets assets = new Assets(MyService.this);
File assetDir = assets.syncAssets();
setupRecognizer(assetDir);
Log.v(TAG, "SET UP DIRECTORIES STARTING LISTENING!");
mSpeechRecognizer.startListening("usersKeyword");
} catch (IOException e) {
e.printStackTrace();
Log.v(TAG, e.toString());
}
setupRecognizer()
public void setupRecognizer(File sphinxDir) {
try {
mSpeechRecognizer = defaultSetup()
.setAcousticModel(new File(sphinxDir, "en-us-ptm"))
.setDictionary(new File(sphinxDir, "cmudict-en-us.dict"))
.setBoolean("-allphone_ci", true)
.setKeywordThreshold(1e-40f)
.getRecognizer();
} catch (IOException e) {
e.printStackTrace();
}
mSpeechRecognizer.addListener(this);
mSpeechRecognizer.addKeyphraseSearch("usersKeyword", keyword.getString("keyword", "oranges and rainbows"));
}
onPartialResult:
#Override
public void onPartialResult(Hypothesis hypothesis) {
if (hypothesis == null) { //no one spoke
return;
}
String text = hypothesis.getHypstr();
Log.v(TAG, "TEXT: " + text + "hypothesis.getHypstr: " + hypothesis.getHypstr());
if (text.equals(keyword.getString("keyword", "oranges and rainbows"))) { //Only happens when text is oranges and rainbows, even after changing preference value!!!
Log.v(TAG, "Heard user keyword!");
mSpeechRecognizer.cancel();
mSpeechRecognizer.startListening("usersKeyword");
}
}
Why is hypothesis.getHypstr() always only one value, even after I change the value of the addKeyphraseSearch?
Thanks,
Ruchir
EDIT:
I actually stop and start the service every time the user changes their input, and so onCreate() is called every time the user changes their data.
FULL CODE:
https://gist.github.com/anonymous/47efc9c1ca08d808e0be
You do not need to destroy the service, you create it once with onCreate.
You can set the command in onStartCommand:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
recognizer.cancel();
recognizer.addKeyphraseSearch("usersKeywords", intent.getStringExtra("keyword"););
recognizer.startListening("usersKeywords");
}
From the other class which is a user of the service you start service with intent:
Intent i = new Intent(this, MyService);
i.putExtra("keyword", "hello");
startService(i);
For more details read documentation
You need to call mSpeechRecognizer.addKeyphraseSearch() every time you want to change the key phrase.
I'm working with notifications generated by every app (not only mine) on my Android device (android 5.1.1).
By extending NotificationListenerService I'm able to know when a push notification is posted (overriding the "onNotificationPosted" method) and when a notification is removed (overriding the "onNotificationRemoved" method).
The problem is that I would like to know how the notification was removed:
a) by clicking it (so opening the app)
or
b) by swyping it (so it is only removed)
?
Is it possible to know it?
Thank you in advance!
The best way to do it is to get the list of all running processes!
So, in the onNotificationRemoved method we can:
1. obtain the list of running processes using the Android Processes library
2. compare each process name with the packageName
3. if the comparison return a true value, we check if the process is in foreground
public void onNotificationRemoved(StatusBarNotification sbn) {
String packageName = sbn.getPackageName();
try {
List<AndroidAppProcess> processes = ProcessManager.getRunningAppProcesses();
if (processes != null) {
for (AndroidAppProcess process : processes) {
String processName = process.name;
if (processName.equals(packageName)) {
if (process.foreground ==true)
{
//user clicked on notification
}
else
{
//user swipe notification
}
}
}
}
}
catch (Exception e)
{
String error = e.toString();
}
}
I have created an app that runs a service to read which app/activity user have opened and using it at the current time. The problem is that the service reads only the launcher application. It doesn't return me the cirrently open app/activity. Can you help? The code i write is below. Thanks in advance.
#Override
public void onStart(Intent intent, int startId) {
// For time consuming an long tasks you can launch a new thread here...
Toast.makeText(this, " Service Started", Toast.LENGTH_LONG).show();
Runnable runable = new Runnable() {
public void run() {
try{
ActivityManager am2 = (ActivityManager) getSystemService(Activity.ACTIVITY_SERVICE);
String packageName = am2.getRunningTasks(1).get(0).topActivity
.getPackageName();
Log.w("RunningTask", packageName);
handler.postDelayed(this, 8000);
}
catch (Exception e){
}
}
};
handler.postDelayed(runable, 8000);
}
If you use Android 5.0 or above, getRunningTasks() is deprecated and will only return a small subset, including the caller's own tasks, and possibly some other tasks such as home.
You may check out getRunningAppProcesses() which worked before Android 5.1.1. See Cannot get foreground activity name in Android Lollipop 5.0 only and Android 5.1.1 and above - getRunningAppProcesses() returns my application package only
Example using getRunningAppProcesses:
ActivityManager am2 = (ActivityManager) getSystemService(Activity.ACTIVITY_SERVICE);
String processName = am2.getRunningAppProcesses().get(0).processName;
Log.w("Running process", processName);