Weemo getCallId returns 0 - java

I am working with the Weemo sdk and up to now it is looking very promising. However I have encountered one problem while writing app based on it. I have registered a CallStatusChanged listener to the eventbus and I have no problem receiving the event on the receiver when the caller calls. However the WeemoCall object is not well constructed and the getCallId() method returns 0 (see the following code ). To my understanding event.getCaller will return the id of the caller so we can latter on use it to establish a call. can anyone help me to solve this ? I have attached a screenshot of the call object I took during debuging.
#WeemoEventListener
public void onCallStatusChanged(final CallStatusChangedEvent event){
String msg = "";
Log.i(TAG,"onCallStatusChanged" + event.toString());
switch (event.getCallStatus()){
case CREATED:
msg = "call created";
break;
...
case RINGING:
msg = "call is ringing";
Intent i = new Intent(this, VideoCallingActivity.class);
i.putExtra(INCOMING_CALL_ID_EXTRA, event.getCall().getCallId()); //getCallId returns 0 ?!
startActivity(i);
break;
...
}
Log.i(TAG,msg);
}

The WeemoCall.getCallId() method returns an int that is used internally as a index.
This way, the first call will have its getCallId() equals to 0, the second will have it equals to 1, and so on and so forth.
So, in order to get the corresponding WeemoCall object on your second activity, you can simply do the following:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int callId = savedInstanceState.getInt(INCOMING_CALL_ID_EXTRA);
WeemoCall call = Weemo.instance().getCall(callId);
}
You could also use this method that will return the current WeemoCall:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WeemoCall call = Weemo.instance().getCurrentCall();
}

Related

How to get icc authentication?

I found some interesting methods in telephonyManager class like turning mobile data off/on but when trying to use them it obviously throws me security exception.("No carrier privilege"). I Googled it, but didn't find any helpful solution.
Because it's carrier privilege I thought it may be possible to get its permission by telephonyManager.getIccAuthentication(int appType, int authType, String data) but I'm having problems with input parameters because I can't figure out what should I pass in to make it work.
From documentation to the first parameter would pass TelephonyManager.APPTYPE_SIM or/and TelephonyManager.APPTYPE_USIM depending on if it has big meaning in using setDataEnabled(boolean).
If I would pass TelephonyManager.APPTYPE_SIM as a first argument I think I should passed TelephonyManager.AUTHTYPE_EAP_SIM as a second argument (correct me if I'm wrong) and vice versa, when TelephonyManager.APPTYPE_USIM as first so TelephonyManager.AUTHTYPE_EAP_AKA as second one.
And then there is the third argument. There must be encoded Base64 to string. I found in TelephonyProvider this line of code:
String base64Challenge = Base64.encodeToString(byteParam, Base64.NO_WRAP); where byteParam is an input byte from another method which is being preceding by thousands other methods. If I pass "" as third parameter to getIccAuthentication method I get again securityException (it's obviously, wrong param) but it throws me lack of getIccSimChallengeResponse. I'm afraid of it may be infinite loop of methods, but maybe someone has any idea or help me to break this through?
My sample code:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.buttonPanel);
button.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onClick(View view) {
try {
Process p = Runtime.getRuntime().exec("su");
tel();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
#RequiresApi(api = Build.VERSION_CODES.O)
private void tel(){
// String base64Challenge = Base64.encodeToString(,
Base64.NO_WRAP);
TelephonyManager telephonyManager = (TelephonyManager)
getSystemService(Context.TELEPHONY_SERVICE);
boolean isCarrier = telephonyManager.hasCarrierPrivileges();
String authentication =
telephonyManager.getIccAuthentication(TelephonyManager.APPTYPE_SIM,
TelephonyManager.AUTHTYPE_EAP_SIM, "");
Log.v(TAG, authentication);
if (isCarrier) {
Log.v(TAG, "privs granted");
telephonyManager.setDataEnabled(false);
} else {
Log.v(TAG, "no privilegies");
}
}
}
From the docs:
Requires Permission: READ_PRIVILEGED_PHONE_STATE or that the calling
app has carrier privileges (see hasCarrierPrivileges()).
The first of those requires you to be installed as a privileged system app (requires root or owning system certificate). The second requires your UID to be the carrier's. Without that no combo of parameters will work.

Best practice using AsyncTask for SharedPreference and general initializing?

First, I have to say I'm kinda new to native Android development. I put the following code inside onCreate in my MainActivity class.
I never used AsyncTask, so I don't know if this is the best practice to do it. Should I create a new AsyncTask-class and load it somehow in the onCreate method? I put it in the MainActivity onCreate method, because of the scope of variables like bp (billing purchase class), pollfish, counting app-launches, etc.
Also I don't know what to return? Because I have multiple results. There are many tutorials how to create an AsyncTask like this and also suggestions to store SharedPreferences there, but I want to know the best practice for it. For example to get values later in my onResume method or similiar operations.
new AsyncTask<Context, Void, String>()
{
#Override
protected String doInBackground(Context... params)
{
Context context = params[0];
SharedPreferences pref = context.getSharedPreferences("Pref",Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
// Count App Launches
totalCount = pref.getInt("counter", 0);
totalCount++;
editor.putInt("counter", totalCount);
editor.apply();
// Pollfish ADS
int pollfishPref = pref.getInt("pollfish", 0);
Log.d(TAG,"Application launch count: " + totalCount);
Log.d(TAG,"pollfish count: " + pollfishPref);
if (!bp.isPurchased(PRODUCT_ID) && (pollfishPref == 0 || (pollfishPref != 0 && pollfishPref <= totalCount)))
{
PollFish.ParamsBuilder paramsBuilder = new PollFish.ParamsBuilder("xxx")
.releaseMode(false)
.customMode(false)
.indicatorPosition(Position.MIDDLE_RIGHT)
.indicatorPadding(0)
.build();
PollFish.initWith(MainActivity.this, paramsBuilder);
mTracker.setScreenName("Pollfish Count: " + pollfishPref + " Applaunch Count: " + totalCount);
mTracker.send(new HitBuilders.ScreenViewBuilder().build());
}
Boolean consumed = pref.getBoolean("consumed", Boolean.parseBoolean(null));
Log.d(TAG,"consumedPref: " + consumed);
if (!consumed)
{
editor.putBoolean("consumed", true);
editor.apply();
bp.consumePurchase(PRODUCT_ID);
Log.d(TAG,"consumed now!");
}
return xxx;
}
protected void onPostExecute(String result)
{
Log.d(TAG, "Preference received in background: " + result);
};
}.execute(this);
Generally, the best practice is for re-use of the AsyncTask and cleaner code by having a separate class. If you are concerned about variable scope, you can pass those into a constructor for your AsyncTask.
class MyAsyncTask extends AsyncTask<Params, Progress, Result> {
private Object arg1;
public MyAsyncTask(Object arg1) {
this.arg1 = arg1;
}
#Override
public Result doInBackground(Params... params) { }
#Override
public void onPostExecute(Result result) { }
}
Of course, update the necessary object types, and use it like so
new MyAsyncTask(arg1).execute();
You may want to update and retrieve values from the SharedPreferences outside of the AsyncTask then pass in those respective values to the constructor as shown.
I don't know what to return? Because I have multiple results.
Sadly, you can only return one type of class. If you are concerned with how to get a result back from the AsyncTask back to where you called it from, then I would recommend callbacks.
You should separate the async task into a separate class and make it extend AsyncTask. You can pass variables you need to use through the constructor. This is the best practice because it can make the code easier to read and doesn't block the main thread

Java android and json - variable confusion

I have an android app that is retrieving data from a mysql db via php.
It works fine, but i have a (simple) variable problem.
I want to create a variable inside MainActivity class.
Then inside MainActiviy class i have onCreate method - and inside that I have some json stuff that retrieves my data from mysql.
I now want to assign some mysql value to the variable i created in MainActivity class (it is assigned inside onResponse method from the json stuff), and then I simply want to use that variable and write it out on a textview, and I will do that in the bottom of the onCreate method.
But for some reason, it "forgets" the value I assigned to the variable, when I have to use it outside the onResponse method.
(if i set the textview text inside the onResponse method, it works fine).
public class MainActivity extends ActionBarActivity {
// I create the variable here
String someString;
TextView text;
RequestQueue reqq;
String showUrl = "http://www.someurl.com/get_data.php";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.textid);
reqq = Volley.newRequestQueue(getApplicationContext());
JsonObjectRequest jsonob = new JsonObjectRequest(Request.Method.POST,
showUrl, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray dataAr = response.getJSONArray("json_data");
for (int i = 0; i < dataAr.length(); i++) {
JSONObject dat = dataAr.getJSONObject(i);
// Here I want to assign some data from my mysql db to the variable
someString = dat.getString("aar");
// If I set the the textview to display value of someString HERE, it works!
// text.setText(someString);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println(error.getMessage());
}
});
reqq.add(jsonob);
// HERE i want to display the value of the variable in the textview!
// - but it doesnt "remember" the value
text.setText(someString);
}
}
If I use static keyword on the someString variable, it remembers the value, but only the SECOND time i open the app!
I'm very new at this, and have tried google, and tried some stuff with a singleton class, but I just don't seem to understand this!
I would love it, if someone could link me some information to help me get this, AND give an example of how my code should be, so it will work!
THANKS! :D
This behavior is due to the fact that
text.setText(someString);
is executed immediately in the onCreate method, & by immediately I mean that it does not wait for any response from the Volley request (the Volley request that you set up before). In other words, you need to wait till you get a response before you set the text on to your TextView.
That's why it successfully sets your TextView's text from within the onResponse method.

Android - losing variables data when partially closing an app

I am using a class with static values called DB (for Data Base) in my application. When I first run the app, a static byte array from this class is filled and used. Then, when I partially close my app (not closing it definitily just put in background) if a reopen it after 20 seconds more or less, the value of the variable is still here but if I let my app in the background for more than 1 minute the value turns to null.
How can I avoid this to happen?
store your variable value to shared preferences and load the value from shared preferences in the onResume() Method of activity and store the value in the onPause() Method.
Handling lifestyle events properly is an important aspect of Android development.
I suggest that you read the following to make sure that you understand what happens to your app when you turn off your screen, change to another application or any other action that might change the state of your app:
http://developer.android.com/training/basics/activity-lifecycle/index.html
My suggestion is to store your data by overriding onSaveInstanceState() like so:
#Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
// Save the user's current game state
savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
Then on your onCreate(), you can reload it like so:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState); // Always call the superclass first
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null)
{
// Restore value of members from saved state
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}
else
{
// Probably initialize members with default values for a new instance
}
...
}
I hope that this helps!
Good luck in your future developing!
I found a solution with the help of the commenters.
For those who had the same problem:
Copy this in all your Activities to ensure that the data is constantly updated in the preferences:
#Override
public void onPause(){
super.onPause();
String bytearray = Base64.encodeToString(DB.bytearray, Base64.DEFAULT);
prefs.edit().putString("BYTEARRAY", bytearray).apply();
}
#Override
public void onResume(){
super.onResume();
String bytearray = prefs.getString("BYTEARRAY", Base64.encodeToString(DB.bytearray, Base64.DEFAULT));
DB.bytearray = Base64.decode(bytearray, Base64.DEFAULT);
}
Then, add this code in all your Activities to ensure that the values are not saved when you close your app.
#Override
public void onDestroy(){
super.onDestroy();
String bytearray = "";
prefs.edit().putString("BYTEARRAY", bytearray).apply();
}

Linked List not updating values

So I've debugged my program and have found that the part of my program is updating, whilst another isn't.
I have a method:
public void storeApplication(String name, String item){
Application app = new Application(name, item);
peopleAttending.add(app);
}
The debugger reports that an object is contained in the LinkedList (peopleAttending).
In another method:
public void populateListView() {
int noOfPeopleAttending = peopleAttending.size();
String noPeopleAttending = String.valueOf(noOfPeopleAttending);
Toast.makeText(GuestsAttending.this, noPeopleAttending, Toast.LENGTH_SHORT).show();
}
This method can be called after the previous one and states that there isn't an object within the LinkedList.
I've checked the object references just to make sure that they are pointing at the same reference and they are.
Any help would be greatly appreciated.
EDIT: Entire Class:
public class GuestsAttending extends Activity {
private LinkedList<Application> peopleAttending = new LinkedList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_guests_attending);
populateListView();
}
public void storeApplication(String name, String item){
Application app = new Application(name, item);
peopleAttending.add(app);
}
public void populateListView() {
// GuestsAdapter adapter = new GuestsAdapter(this, peopleAttending);
// ListView listView = (ListView) findViewById(R.id.listView);
// listView.setAdapter(adapter);
peopleAttending.size();
int noOfPeopleAttending = peopleAttending.size();
String noPeopleAttending = String.valueOf(noOfPeopleAttending);
Toast.makeText(GuestsAttending.this, noPeopleAttending, Toast.LENGTH_SHORT).show();
}
Second Edit:
Java Booking Screen Method:
public void saveBookingInfo(View view) {
GuestsAttending sendApplication = new GuestsAttending();
EditText applicantNameText = (EditText) findViewById(R.id.applicantNameTextField);
EditText itemToBurnText = (EditText) findViewById(R.id.itemToBurnTextField);
String appName = applicantNameText.getText().toString();
String appItemToBurn = itemToBurnText.getText().toString();
if (appItemToBurn.isEmpty() || appName.isEmpty()) {
Toast.makeText(BookingScreen.this, "Please fill in all fields.", Toast.LENGTH_SHORT).show();
}
else {
sendApplication.storeApplication(appName, appItemToBurn);
}
}
GuestsAttending Java Class: -- See Above.
Useful hint: It's really popular to set type of List as a List<> interface from java.util package instead of LinkedList<> itself.
Anyway, i am pretty sure that storeApplication method is not automatically triggered before onCreate method ran by Activity framework. Maybe your debugger is stopoing on it in different order (because of using threads or smth), but you should to log some invoke. Try to find it out.
I've found out what the problem is:
When I submit the booking information, it runs all the necessary methods. However, when the "storeApplication()" method has finished executing, the ArrayList 'empties' all the objects out.
I only noticed this when I used breakpoint and tried running the method twice, on the second time I entered booking details, the ArrayList stated it was empty.
I'm going to see if I can try and store the ArrayList in a more secure place.

Categories