I'd like to use the static String getLastOutgoingCall() method in order to pull the duration of the last outgoing phone call but I don't know how !
I'm a beginner with java programming (I usually program in c++)
The tutorials that I found use the ancient APIs and none of them use the method I'm talking about.
I hope I have not misinterpreted your question. If so, please let me know.
The method String getLastOutgoingCall (Context context) from android.provider.CallLog.Calls, according to the documentation, returns
The last phone number dialed (outgoing) or an empty string if none
exist yet.
So, you can't retrieve the last outgoing call duration using that method.
To get the last outgoing call duration, you can query the CallLog.Calls.CONTENT_URI to retrieve this info.
You can use a method like this:
public String getLastOutgoingCallDuration(final Context context) {
String output = null;
final Uri callog = CallLog.Calls.CONTENT_URI;
Cursor cursor = null;
try {
// Query all the columns of the records that matches "type=2"
// (outgoing) and orders the results by "date"
cursor = context.getContentResolver().query(callog, null,
CallLog.Calls.TYPE + "=" + CallLog.Calls.OUTGOING_TYPE,
null, CallLog.Calls.DATE);
final int durationCol = cursor
.getColumnIndex(CallLog.Calls.DURATION);
// Retrieve only the last record to get the last outgoing call
if (cursor.moveToLast()) {
// Retrieve only the duration column
output = cursor.getString(durationCol);
}
} finally {
// Close the resources
if (cursor != null) {
cursor.close();
}
}
return output;
}
Note: To perform this query you will need to add the following permission to your manifest:
<uses-permission android:name="android.permission.READ_CALL_LOG" />
Edit based on your own answer:
You need to call the getLastOutgoingCallDuration() on the onCreate() method of your Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); // Here you need to set the name of your xml
TextView displayDuration;
displayDuration = (TextView) findViewById(R.id.textView2);
String duration = getLastOutgoingCallDuration(this);
displayDuration.setText(output + "sec");
}
Related
I'm using socket.io for my chat app. I have an ArrayList which contains last message, username, time. Whenever a new message arrives in JSON format then it should check if JSON contained username is present in ArrayList or not. If present, then updates the ArrayList otherwise add in ArrayList.
Here is my code:-
private Emitter.Listener handle1 = new Emitter.Listener() {
#Override
public void call(final Object... args) {
ChatLists.this.runOnUiThread(new Runnable() {
#Override
public void run() {
JSONObject data = (JSONObject)args[0];
try {
String sendername = data.getString("sender");
String lastMessage = data.getString("message");
String profileImage = data.getString("Profile");
String token = data.getString("fb_token");
chat_list chat_list = new chat_list(sendername,
profileImage, lastMessage, "0", "", "dummy", token);
if (chat_lists.size()==0){
chat_lists.add(chat_list);
}else {
for (int i=0;i<chat_lists.size();i++){
if (chat_lists.get(i).getContactname().equals(sendername)){
chat_lists.set(i,chat_list);
}else {
chat_lists.add(chat_list)
}
}
}
contactlistAdapter = new ContactlistAdapter(chat_lists);
recyclerView.setAdapter(contactlistAdapter);
contactlistAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
};
Well, you can use contains() & set() methods of ArrayList in a logical way to solve your problem like below:-
if(chat_lists.contains(username))
chat_lists.set(indexOf(username), new_username);
else chat_lists.add(new_username);
Try it:
if(chat_lists.contains(chat_list)){
chat_lists.remove(chat_list);
chat_lists.add(chat_list);
} else {
chat_lists.add(chat_list);
}
Read about architecture patterns, for example, MVP.
You need to store your messages somethere (in Model) and update view relative to data.
Also read about RecyclerView, cause of ListView is a little bit deprecated
if (chat_lists.get(i).getContactname().equals(sendername)){
above statement has problem them. It's not getting under your if condition and following the chat_lists.add(chat_list) statement.
Instead equals use ignoreCasequals. If still wont it solve your problem please use debug mode or logs check chat_lists.get(i).getContactname()
and sendername same or not.
I want to save a value in login page that I can use afterwards in other fragments. For doing this I used sharedPreferences and could store the "username", and here is the code:
Login.java
btnl.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// get The User name and Password
String userName=un.getText().toString();
String password=pa.getText().toString();
String PATIENTID="";
// fetch the Password form database for respective user name
String storedPassword=demoCRUD.getSingleEntry_Username(userName);
// check if the Stored password matches with Password entered by user
if(password.equals(storedPassword)) {
show("Welcome!");
SharedPreferences userDetails = getContext().getSharedPreferences("userdetails", Context.MODE_PRIVATE);
Editor edit = userDetails.edit();
edit.clear();
edit.putString("_user", userName.trim());
edit.apply();
Intent intentLogin=new Intent(getActivity(),Welcome.class);
startActivity(intentLogin);
}
else {
show("User Name or Password does not match");
}
}
});
In addition I could fetch the value again using sharedPreferences in other fragment using the following code:
EditPersonal.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ep_demoCRUD = new DemographicsCRUD(getActivity());
SharedPreferences userDetails = getContext().getSharedPreferences("userdetails", Context.MODE_PRIVATE);
String puser = userDetails.getString("_user", "");
show("puser = " + puser); *SHOWS ME IT HAS A STRING INSIDE
}
Also in "EditPersonal.java" I have this piece of code that call a method from different class:
protected Long doInBackground(Void... arg0) {
return ep_demoCRUD.UpdateDemographics(ep_demoId,puser);
}
The problem is that when onCreate method of "EditPersonal.java" run, "puser" has a value equal to the username from Login.java, but once "doInBachground" call the method "ep_demoCRUD.UpdateDemographics(ep_demoId,puser);" it pass null!
I printed the Log and I understood puser=null.
I can't understand what is the problem? why "null" is passed while it has already had the value ?
p.s the method UpdateDemographics is defined as following:
public long UpdateDemographics(Demographics_to demoId,String us) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(DataBaseHelper.lastName, demoId.getD_lastName());
values.put(DataBaseHelper.firstName, demoId.getD_firstName());
values.put(DataBaseHelper.dateOfBirth, demoId.getD_dateOfBirth());
Log.d("puser","=" +us); * NULL IS PRINTED IN LOG*
long result = database.update(dbHelper.Demographics_Table,values,"username = ?" , new String[]{us});
Log.d("Update Result:", "=" + result);
db.close();
return result;
}
Thank you in advance!
i think you are using two variable with same name puser ,, one of them global and the other is Local ,, Just make sure if thats true or not ,, if not then show me the full code of class EditPersonal.java
doInBackground(Void... arg0){}
You do not give the puser variable in the AsyncTask. Why not? is puser a global var?
try giving the puser var with the AsyncTask.
doInBackground(String... puser) {
return ep_demoCRUD.UpdateDemographics(ep_demoId,puser);
}
can you post the whole AsyncTask and where puser is defined?
Why are you using editor.clear()? If you want to store, replace editor.clear() with editor.commit();
I am trying to retrieve string data from a column in database and insert into a string array in android. I have used the following code to retrieve data - (helper.java)
public String[] personslist() {
// TODO Auto-generated method stub
int i=0;
Cursor c=myDataBase.rawQuery("select PersonName from Persons;",null);
String[] values = {};
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
values[i] = c.getString(c.getColumnIndex("PersonName"));
i++;
}
return values;
}
I have used the following code in "adapter.java" class to return the data returned by personslist().
public String[] plist() {
// TODO Auto-generated method stub
String[] persons = mDbHelper.personslist(); //this is line no. 131 in adapter class
return persons;
}
While I am running the application, it is getting crashed and showwing the following error
09-08 08:23:19.715: E/AndroidRuntime(29373): Caused by: java.lang.NullPointerException
09-08 08:23:19.715: E/AndroidRuntime(29373): at com.example.fromstart.adapter.plist(adapter.java:131)
The query, when run on sqlitebrowser, it returns four rows of four persons names. But, while running on an application, it is returning NullPointerException. Can you please suggest me, where I might have gone wrong?
Thanks in advance.
mDbHelper is null. That's what's throwing your exception. Make sure it gets initialized.
Check where you are initialzing the mDbHelper. You are doing mDbHelpe.personslist(). and here your mDbHelper could be Null and so nullpointer exception.
Did u do anything similar to this to initialize
Context context;
SQLiteDatabase db = null ;
CallDBHelper dbHelp = null;
public Constructor(Context context) {
this.context = context;
dbHelp = new CallDBHelper(context);
db = dbHelp.getWritableDatabase();
}
Cursor c = db.query(...
I grab a code from the android site that do the reverse geocoding (transfering a location from numbers to a text)
It's working fine but since my application has changed a bit I need to change this code into a normal method, right now it's an AsyncTask. It should get a Location and return a string.
This code is a bit strange to me so I need your help guys:
private class ReverseGeocodingTask extends AsyncTask<Location, Void, Void>
{
Context mContext;
public ReverseGeocodingTask(Context context)
{
super();
mContext = context;
}
#Override
protected Void doInBackground(Location... params)
{
Geocoder geocoder = new Geocoder(mContext, Locale.getDefault());
Location loc = params[0];
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(loc.getLatitude(), loc.getLongitude(), 1);
} catch (IOException e) {
e.printStackTrace();
// Update address field with the exception.
LocationService.this.address = e.toString();
}
if (addresses != null && addresses.size() > 0)
{
Address address = addresses.get(0);
// Format the first line of address (if available), city, and country name.
String addressText = String.format("%s, %s, %s",
address.getMaxAddressLineIndex() > 0 ? address.getAddressLine(0) : "",
address.getLocality(),
address.getCountryName());
// Update address field on UI.
// Message.obtain(mHandler, UPDATE_ADDRESS, addressText).sendToTarget();
LocationService.this.address = addressText;
}
return null;
}
}
You start by making a method like so
public String reverseGeocode(Location loc) {
}
change the line that grabs the first location, being the only one used, and remove it - you already have loc
//Location loc = params[0];
Then instead of setting the address to that location service, just return it:
//LocationService.this.address = addressText;
return addressText;
Splice those into the method, remove the unnecessary return statement at the end, and you're golden.
Upon a closer look I'm also seeing an exception you'll simply want to throw up the chain instead of handling inside this method. Let that get handled by whatever calls your method on a case-by-case basis: it's not a problem this method can solve.
A month ago, I dropped-in ActionBarSherlock 4.2 into my project. I got everything to work, except the search suggestions for my SearchView. The way I was creating search suggestions was using the method in the Android documentation.
Does ActionBarSherlock support search suggestions? I tried to dig through the issue list on the Github page but the issue seems closed but I can't seem to follow the discussion and understand whether it really is a resolved or not. I thought that some of you who've been using ActionBarSherlock might know better.
It doesn't. But I have found a way to make it query your ContentProvider.
I looked into the source of SuggestionsAdapter from API 17 where the query executes and got an idea of replacing this method. Also I found that ActionbarSherlock's SuggestionsAdapter does not use your SearchableInfo.
Edit com.actionbarsherlock.widget.SuggestionsAdapter in your ActionBarSherlock project:
Add a line
private SearchableInfo searchable;
in constructor, add
this.searchable = mSearchable;
Replace getSuggestions method with this one:
public Cursor getSuggestions(String query, int limit) {
if (searchable == null) {
return null;
}
String authority = searchable.getSuggestAuthority();
if (authority == null) {
return null;
}
Uri.Builder uriBuilder = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority)
.query("") // TODO: Remove, workaround for a bug in Uri.writeToParcel()
.fragment(""); // TODO: Remove, workaround for a bug in Uri.writeToParcel()
// if content path provided, insert it now
final String contentPath = searchable.getSuggestPath();
if (contentPath != null) {
uriBuilder.appendEncodedPath(contentPath);
}
// append standard suggestion query path
uriBuilder.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY);
// get the query selection, may be null
String selection = searchable.getSuggestSelection();
// inject query, either as selection args or inline
String[] selArgs = null;
if (selection != null) { // use selection if provided
selArgs = new String[] { query };
} else { // no selection, use REST pattern
uriBuilder.appendPath(query);
}
if (limit > 0) {
uriBuilder.appendQueryParameter("limit", String.valueOf(limit));
}
Uri uri = uriBuilder.build();
// finally, make the query
return mContext.getContentResolver().query(uri, null, selection, selArgs, null);
}
Now it queries my ContentProvider but crashes with default adapter saying that no layout_height loading some xml file from support library. So you have to use custom SuggestionsAdapter. This is what worked for me:
import com.actionbarsherlock.widget.SearchView;
import android.app.SearchManager;
import android.app.SearchableInfo;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public final class DrugsSearchAdapter extends CursorAdapter
{
private static final int QUERY_LIMIT = 50;
private LayoutInflater inflater;
private SearchView searchView;
private SearchableInfo searchable;
public DrugsSearchAdapter(Context context, SearchableInfo info, SearchView searchView)
{
super(context, null, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
this.searchable = info;
this.searchView = searchView;
this.inflater = LayoutInflater.from(context);
}
#Override
public void bindView(View v, Context context, Cursor c)
{
String name = c.getString(c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1));
TextView namet = (TextView) v.findViewById(R.id.list_item_drug_name);
namet.setText(name);
String man = c.getString(c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2));
TextView manuf = (TextView) v.findViewById(R.id.list_item_drug_manufacturer);
manuf.setText(man);
}
#Override
public View newView(Context arg0, Cursor arg1, ViewGroup arg2)
{
return this.inflater.inflate(R.layout.list_item_drug_search, null);
}
/**
* Use the search suggestions provider to obtain a live cursor. This will be called
* in a worker thread, so it's OK if the query is slow (e.g. round trip for suggestions).
* The results will be processed in the UI thread and changeCursor() will be called.
*/
#Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
String query = (constraint == null) ? "" : constraint.toString();
/**
* for in app search we show the progress spinner until the cursor is returned with
* the results.
*/
Cursor cursor = null;
if (searchView.getVisibility() != View.VISIBLE
|| searchView.getWindowVisibility() != View.VISIBLE) {
return null;
}
try {
cursor = getSuggestions(searchable, query, QUERY_LIMIT);
// trigger fill window so the spinner stays up until the results are copied over and
// closer to being ready
if (cursor != null) {
cursor.getCount();
return cursor;
}
} catch (RuntimeException e) {
}
// If cursor is null or an exception was thrown, stop the spinner and return null.
// changeCursor doesn't get called if cursor is null
return null;
}
public Cursor getSuggestions(SearchableInfo searchable, String query, int limit) {
if (searchable == null) {
return null;
}
String authority = searchable.getSuggestAuthority();
if (authority == null) {
return null;
}
Uri.Builder uriBuilder = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority)
.query("")
.fragment("");
// if content path provided, insert it now
final String contentPath = searchable.getSuggestPath();
if (contentPath != null) {
uriBuilder.appendEncodedPath(contentPath);
}
// append standard suggestion query path
uriBuilder.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY);
// get the query selection, may be null
String selection = searchable.getSuggestSelection();
// inject query, either as selection args or inline
String[] selArgs = null;
if (selection != null) { // use selection if provided
selArgs = new String[] { query };
} else { // no selection, use REST pattern
uriBuilder.appendPath(query);
}
if (limit > 0) {
uriBuilder.appendQueryParameter("limit", String.valueOf(limit));
}
Uri uri = uriBuilder.build();
// finally, make the query
return mContext.getContentResolver().query(uri, null, selection, selArgs, null);
}
}
And set this adapter in SearchView
searchView.setSuggestionsAdapter(new DrugsSearchAdapter(this, searchManager.getSearchableInfo(getComponentName()), searchView));
I'm the one that opened the github issue for this. It is working on the dev branch. The current version (4.2) doesn't have the fix. It was completely fixed by this commit, but I would suggest just checking out the dev branch and trying it.
I don't know if I'm wrong here or I changed something on accident, but the above answer does not work and the ActionBarSherlock SuggestionsAdapter does not work. All I get are null pointers in runQueryOnBackgroundThread. It never goes into bindView etc. either, yet it manages to display suggestion results. I think android.app.SearchManager is somehow overriding ABS with getSuggestions() but I'm not sure. I'm still trying things out...