Service unable to start activity of other app - android

I have an application "x" that starts a service(in some other package) on button click. This service should now read call logs and send data to application "y" which should write the data in sd card. Presently, my service runs on button click but the application "y" doesn't as I have a toast in application "y" and it never comes up. The permissions are given in for reading logs and since am using custom action the same is included in intent filter of application "y". Can someone tell the reason for this problem.
service code
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("TAG", "Service started.");
super.onStartCommand(intent, flags, startId);
StringBuffer sb = new StringBuffer();
String strOrder = android.provider.CallLog.Calls.DATE + " DESC";
/* Query the CallLog Content Provider */
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return 0;
}
Cursor managedCursor = getContentResolver().query(CallLog.Calls.CONTENT_URI, null,
null, null, strOrder);
int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
sb.append("Call Log :");
int h = 0;
while (managedCursor.moveToNext() && h != 20) {
String phNum = managedCursor.getString(number);
String callTypeCode = managedCursor.getString(type);
String strcallDate = managedCursor.getString(date);
Date callDate = new Date(Long.valueOf(strcallDate));
String callDuration = managedCursor.getString(duration);
String callType = null;
h++;
int callcode = Integer.parseInt(callTypeCode);
switch (callcode) {
case CallLog.Calls.OUTGOING_TYPE:
callType = "Outgoing";
break;
case CallLog.Calls.INCOMING_TYPE:
callType = "Incoming";
break;
case CallLog.Calls.MISSED_TYPE:
callType = "Missed";
break;
}
sb.append("\nPhone Number:--- " + phNum + " \nCall Type:--- "
+ callType + " \nCall Date:--- " + callDate
+ " \nCall duration in sec :--- " + callDuration);
sb.append("\n----------------------------------");
}
managedCursor.close();
managedCursor.close();
Intent sendIntent = new Intent();
String CUSTOM_ACTION = "com.example.sonali.callreadingservice.CALL_LOGS";
sendIntent.setAction(CUSTOM_ACTION);
sendIntent.putExtra(Intent.EXTRA_TEXT, (Serializable) sb);
sendIntent.setType("text/plain");
startActivity(sendIntent);
this.stopSelf();
return 0;
}
#Override
public void onDestroy() {
Log.d("slog", "onDestroy()");
super.onDestroy();
}
application "y" main activity
``public class MainActivity extends AppCompatActivity {
TextView textView = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
textView = (TextView) findViewById(R.id.textview_call);
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
handleSendText(intent);
}
void handleSendText(Intent intent) {
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
try {
if (sharedText != null) {
textView.setText(sharedText);
File sdCard = Environment.getExternalStorageDirectory();
FileWriter writer = new FileWriter(sdCard);
// Writes the content to the file
writer.write(sharedText);
writer.flush();
writer.close();
}
} catch (Exception e) {
}
}
intent-filter of application "y"
`
`<intent-filter>
<action android:name="com.example.sonali.callreadingservice.CALL_LOGS" />
<category android:name="android.intent.category.LAUNCHER" />
<data android:mimeType="text/plain" />
</intent-filter>

You need to add your custom action in the Manifest to the Activity.
<activity
android:name="MainActivity">
<intent-filter>
<action android:name="com.example.sonali.callreadingservice.CALL_LOGS"/>
</intent-filter>
</activity>

Related

call broadcast receiver being triggered three times

public class callLogs extends BroadcastReceiver {
String phNumber, callType, callDate, callDuration, dir;
Date callDayTime;
List<calls> data = new ArrayList<>();
SharedPreferences pref;
SharedPreferences.Editor edit;
ConnectionDetector cd;
private callsData callsData;
private callsDb callsDb;
private static final String DATABASE_NAME = "callsData";
#Override
public void onReceive(final Context context, Intent intent) {
pref = context.getSharedPreferences("pref", Context.MODE_PRIVATE);
edit = pref.edit();
callsData = Room.databaseBuilder(context.getApplicationContext(),
callsData.class, DATABASE_NAME).fallbackToDestructiveMigration().build();
// cd = new ConnectionDetector(context.getApplicationContext());
CountDownTimer countDownTimer = new CountDownTimer(500 , 1000) {
#Override
public void onTick(long l) {
}
#Override
public void onFinish() {
StringBuffer sb = new StringBuffer();
String strOrder = android.provider.CallLog.Calls.DATE + " DESC";
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
Cursor managedCursor = context.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, strOrder);
int name = managedCursor.getColumnIndex(CallLog.Calls.CACHED_NAME);
int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
sb.append("Call Details :");
managedCursor.moveToFirst();
// while (managedCursor.moveToNext()) {
String pName = managedCursor.getString(name);
phNumber = managedCursor.getString(number); // mobile number
callType = managedCursor.getString(type); // call type
callDate = managedCursor.getString(date); // call date
callDayTime = new Date(Long.valueOf(callDate));
callDuration = managedCursor.getString(duration);
dir = null;
// Log.d("Name",pName);
int dircode = Integer.parseInt(callType);
switch (dircode) {
case CallLog.Calls.OUTGOING_TYPE:
dir = "OUTGOING";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "INCOMING";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED";
break;
case CallLog.Calls.REJECTED_TYPE:
dir = "REJECTED";
break;
}
new Thread(new Runnable() {
#Override
public void run() {
callsDb = new callsDb();
callsDb.setPhone(phNumber);
callsDb.setType(dir);
callsDb.setDate(String.valueOf(callDayTime));
callsDb.setDuration(callDuration);
callsData.callsDao().insertAll(callsDb);
}
}).start();
sb.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- " + dir + " \nCall Date:--- " + callDayTime + " \nCall duration in sec :--- " + callDuration);
sb.append("\n----------------------------------");
// }
managedCursor.close();
// textView.setText(sb);
Log.d("Agile", sb.toString());
Log.d("data",callsDb.getPhone());
Log.d("type kya hai",callsDb.getType());
calls person = new calls();
person.setMobile(callsDb.getPhone());
person.setType(callsDb.getType());
person.setDate(callsDb.getDate());
person.setDuration(callsDb.getDuration());
data.add(person);
Bean b = (Bean) context.getApplicationContext();
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(b.baseURL)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
Allapi cr = retrofit.create(Allapi.class);
callsBean body = new callsBean();
body.setCallLogs(data);
Gson gsonObj = new Gson();
String jsonStr = gsonObj.toJson(body);
String id = pref.getString("id", "");
Log.d("id", id);
Log.d("id", pref.getString("id", ""));
Log.d("id", jsonStr);
Call<callsBean> call = cr.calls(id, jsonStr);
call.enqueue(new Callback<callsBean>() {
#Override
public void onResponse(Call<callsBean> call, Response<callsBean> response) {
Log.d("response", response.body().getCallLogs().toString());
/*new Thread(new Runnable() {
#Override
public void run() {
callsData.callsDao().delete(callsDb);
}
}).start();*/
}
#Override
public void onFailure(Call<callsBean> call, Throwable t) {
}
});
}
};
countDownTimer.start();
}
I have created a BroadcastReceiver for call code is working fine and storing data in Room Database, latest call is being stored but there i am calling an Api to store data on server as well getting from Room Databse
but the problem is Api being hit three times i think because of broadcast
receiver.
When call is incoming first api will hit on incoming the second on receiving time and third it will hit on end call time, this happening as well in missed call and outgoing call time.
please help me to find the solution for this.
i want Api should hit only one time

How to get dual sim number call logs?

How to get dual sim number call logs in android. I followed below link to get the dual sim call logs but this method returns -1 always.
I tried other stackoverflow not much answers for dual sim call logs which is available from api 21.
https://stackoverflow.com/a/23907166/6891712
I have tried using the below method which give only the call details but not able to find that from which sim the call is dialed or received
private void getCalldetailsNow() {
#SuppressLint("MissingPermission") Cursor managedCursor=c.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DATE + " DESC");
int number = 0;
if (managedCursor != null) {
number = managedCursor.getColumnIndex( CallLog.Calls.NUMBER );
}
int duration1 = managedCursor.getColumnIndex( CallLog.Calls.DURATION);
int type1=managedCursor.getColumnIndex(CallLog.Calls.TYPE);
int date1=managedCursor.getColumnIndex(CallLog.Calls.DATE);
int idSimId = getSimIdColumn(managedCursor);
if( managedCursor.moveToFirst() == true ) {
String phNumber = managedCursor.getString(number);
String callDuration = managedCursor.getString(duration1);
String type=managedCursor.getString(type1);
String date=managedCursor.getString(date1);
String gettSimNumber=managedCursor.getString(idSimId);
String dir = null;
int dircode = Integer.parseInt(type);
switch (dircode)
{
case CallLog.Calls.OUTGOING_TYPE:
dir = "OUTGOING";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "INCOMING";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED";
break;
default:
dir = "MISSED";
break;
}
}
managedCursor.close();
}
public static int getSimIdColumn(final Cursor c) {
for (String s : new String[] { "sim_id", "simid", "sub_id" }) {
int id = c.getColumnIndex(s);
if (id >= 0) {
Log.d(" Simmmm", "sim_id column found: " + s);
return id;
}
}
Log.d(" Simmmm", "no sim_id column found");
return -1;
}
Try this method to read sim card contact ..
if you want to read first device store contact then implement to implements LoaderManager.LoaderCallbacks into class..
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(getActivity(),
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, ProfileQuery.PROJECTION,
// Select only email addresses
null, null, null);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
List<String> numbers = new ArrayList<>();
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
String phoneNumber = cursor.getString(ProfileQuery.NUMBER).replaceAll("\\D", "");
CustomLogHandler.printDebuglog(TAG, "onLoadFinished: " + phoneNumber);
if (!TextUtils.isEmpty(phoneNumber) && !phoneNumber.startsWith(Constants.SP_COUNTRY_CODE)) {
mCountryCodeList.add(new StringBuilder().append(Constants.SP_COUNTRY_CODE).toString());
alPhoneNumbers.add(new StringBuilder().append(Constants.SP_COUNTRY_CODE).append(phoneNumber).toString());
} else {
mCountryCodeList.add(new StringBuilder().append(Constants.SP_COUNTRY_CODE).toString());
alPhoneNumbers.add(phoneNumber);
}
names.add(cursor.getString(ProfileQuery.NAME));
cursor.moveToNext();
}
allPhoneNumberName.addAll(names);
}
this below class read sim card data..
private class ReadContactFromSIMCard extends AsyncTask<Object, Object, Object> {
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
requestForContact();
}
#Override
protected Object doInBackground(Object[] params) {
Cursor cursorSim = null;
try {
String phoneNo;
String name;
Uri simUri = Uri.parse("content://icc/adn");
cursorSim = getActivity().getContentResolver().query(simUri, null, null, null, null);
if (cursorSim != null) {
while (cursorSim.moveToNext()) {
name = cursorSim.getString(cursorSim.getColumnIndex("name"));
phoneNo = cursorSim.getString(cursorSim.getColumnIndex("number"));
if (!TextUtils.isEmpty(name)) {
allPhoneNumberName.add(name);
}
if (!TextUtils.isEmpty(phoneNo)) {
phoneNo.replaceAll("\\D", "");
phoneNo.replaceAll("&", "");
if (!TextUtils.isEmpty(phoneNo) && !phoneNo.startsWith(Constants.SP_COUNTRY_CODE)) {
mCountryCodeList.add(Constants.SP_COUNTRY_CODE);
alPhoneNumbers.add(Constants.SP_COUNTRY_CODE + phoneNo);
} else {
mCountryCodeList.add(Constants.SP_COUNTRY_CODE);
alPhoneNumbers.add(phoneNo);
}
}
}
}
} catch (Throwable e) {
CustomLogHandler.printErrorlog(e);
} finally {
if (cursorSim != null) {
cursorSim.close();
}
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
getLoaderManager().initLoader(0, null, FindFriendsFragment.this);
}
}
get call log details...
private void getCallDetails() {
StringBuffer sb = new StringBuffer();
Uri contacts = CallLog.Calls.CONTENT_URI;
Cursor managedCursor = this.getContentResolver().query(contacts, null, null, null, null);
int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
sb.append("Call Details :");
while (managedCursor.moveToNext()) {
HashMap rowDataCall = new HashMap<String, String>();
String phNumber = managedCursor.getString(number);
String callType = managedCursor.getString(type);
String callDate = managedCursor.getString(date);
String callDayTime = new Date(Long.valueOf(callDate)).toString();
// long timestamp = convertDateToTimestamp(callDayTime);
String callDuration = managedCursor.getString(duration);
String dir = null;
int dircode = Integer.parseInt(callType);
switch (dircode) {
case CallLog.Calls.OUTGOING_TYPE:
dir = "OUTGOING";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "INCOMING";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED";
break;
}
sb.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- " + dir + " \nCall Date:--- " + callDayTime + " \nCall duration in sec :--- " + callDuration);
sb.append("\n----------------------------------");
Uri allCalls = Uri.parse("content://call_log/calls");
Cursor c = managedQuery(allCalls, null, null, null, null);
String id = c.getString(c.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID));
Log.d("sim",id);
}
managedCursor.close();
System.out.println(sb);
}
and i hope you add below permission into android manifest file ..
<uses-permission android:name="android.permission.READ_CALL_LOG" />
Maybe you can get subscription_id by get "Calls.PHONE_ACCOUNT_ID" item, which called "The identifier for the account used to place or receive the call."
And after you get the subscription_id, which is match slot id, for example, slot 0 is subscription_id 0, and slot id 1 is subscription_id 1, then you can getSlotIndex using giveb subid, then you can using this slotid to query calls from this slot or to this slot.

call logs of particular number

i want to display call logs of particular caller the number is getting from another activity but query which i tried not working please give solution. code which are in comments are what i tried.
thanks
public class CallLogs extends Activity {
TextView tv,tv2;
//ListView lv;
//SimpleCursorAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_call_logs);
tv=(TextView)findViewById(R.id.textView1);
tv2=(TextView)findViewById(R.id.textView2);
//lv=(ListView)findViewById(R.id.listView1);
getCallDetails();
String phone = getIntent().getExtras().getString("Phone");
tv2.setText(phone);
}
private void getCallDetails() {
String phone = getIntent().getExtras().getString("Phone");
StringBuffer sb = new StringBuffer();
String strOrder = android.provider.CallLog.Calls.DATE + " DESC";
/* Query the CallLog Content Provider */
Cursor managedCursor = managedQuery(CallLog.Calls.CONTENT_URI, null,
/*CallLog.Calls.NUMBER+" = ?"*/null,/*new String[]{phone}*/null, strOrder);
int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
sb.append("Call Log :");
while (managedCursor.moveToNext()) {
String phNum = managedCursor.getString(number);
String callTypeCode = managedCursor.getString(type);
String strcallDate = managedCursor.getString(date);
Date callDate = new Date(Long.valueOf(strcallDate));
String callDuration = managedCursor.getString(duration);
String callType = null;
int callcode = Integer.parseInt(callTypeCode);
switch (callcode) {
case CallLog.Calls.OUTGOING_TYPE:
callType = "Outgoing";
break;
case CallLog.Calls.INCOMING_TYPE:
callType = "Incoming";
break;
case CallLog.Calls.MISSED_TYPE:
callType = "Missed";
break;
}
sb.append("Phone Number: " + phNum + " \nCall Type:"
+ callType + " \nCall Date: " + callDate
+ " \nCall duration in sec : " + callDuration);
sb.append("\n--------------------------");
// adapter = new SimpleCursorAdapter(this,R.layout.custcontview,managedCursor,new String[]{"NUMBER","TYPE","DATE","DURATION"},new int[] {R.id.ccontNo,R.id.ccontName,R.id.ccontType,R.id.textView1});
}
tv.setText(sb);
// lv.setAdapter(adapter);
// managedCursor.close();
}
}
Add the following permission in manifest
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
Use the following code to retreive log
public void getLogsByNumber(String[] strNumber ) {
Cursor cursor = getContentResolver().query(CallLog.Calls.CONTENT_URI, null, CallLog.Calls.NUMBER + " = ? ", strNumber , "");
if (cursor.moveToFirst ()) {
while (cursor.moveToNext ()) {
String id = cursor.getString (cursor.getColumnIndex (CallLog.Calls._ID));
String number = cursor.getString (cursor.getColumnIndex (CallLog.Calls.NUMBER));
String name = cursor.getString (cursor.getColumnIndex (CallLog.Calls.CACHED_NAME));
}
}
}

How to get Dialled PhoneNumber?

I want to get the dialled phonenumber
For getting the incomming call number I used this code, it worked fine
number = intent.getStringExtra("incoming_number");
I searched regarding how can I get the dialled number and I got a common code everywhere, and I used this in my program but its giving nullpointer exception, So can anyone tell what mistake I am making or how may I calculate dialled phone number
else if (callstate == TelephonyManager.CALL_STATE_OFFHOOK) {
Log.i("state", "offhook state");
number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.i("number", number);
}
In the manifest:
<receiver android:name="Incommingcall" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.CALL_PRIVILEGED" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
At the time of outgoing call, your intent action will be Intent.ACTION_NEW_OUTGOING_CALL in onReceive
So you can try this:
#Override
public void onReceive(final Context context, final Intent intent) {
if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
dialled_num = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
}
}
Refer here for more info.
Hope it helps.
Try this to get all call types:
private void getCallDetails()
{
final StringBuffer sb = new StringBuffer();
Cursor managedCursor = managedQuery(CallLog.Calls.CONTENT_URI, null, null, null, null);
int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
sb.append("Call Details :");
while (managedCursor.moveToNext())
{
String phNumber = managedCursor.getString(number);
String callType = managedCursor.getString(type);
String callDate = managedCursor.getString(date);
Date callDayTime = new Date(Long.valueOf(callDate));
String callDuration = managedCursor.getString(duration);
String dir = null;
int dircode = Integer.parseInt(callType);
switch (dircode)
{
case CallLog.Calls.OUTGOING_TYPE:
dir = "DIALED";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "RECEIVED";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED";
break;
}
sb.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- " + dir + " \nCall Date:--- " + callDayTime + " \nCall duration in sec :--- " + callDuration);
sb.append("\n----------------------------------");
}
managedCursor.close();
call.setText(sb.toString());
}
}

android service to keep track of outgoing calls and SMS in background

I want to write a service in android which will keep track of outgoing calls and SMS in background. Whenever an outgoing call event or outgoing SMS event is received, I want to fetch the details like phone number, date, call duration (in case of outgoing call) and cost of call or SMS. I want to save these details in local database.
I tried using broadcast receiver along with services, but I am not able to calculate the actual call duration. And for SMS I found out that we need to check the SMS folder after some particular time period whether it is updated. Is there any event which will notify after the SMS is sent.
Following is the Code I have tried so far-
My MainActivity.java
public class MainActivity extends Activity {
TextView call = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
call = (TextView) findViewById(R.id.call);
Intent intent = new Intent(this, HelloService.class);
startService(intent);
}
}
My Service Class
public class HelloService extends Service {
CallDurationReceiver receiver = null;
#Override
public void onCreate() {
receiver = new CallDurationReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
filter.addAction(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED);
registerReceiver(receiver, filter);
HandlerThread thread = new HandlerThread("ServiceStartArguments");
thread.start();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
// If we get killed, after returning from here, restart
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
#Override
public void onDestroy() {
unregisterReceiver(receiver);
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
}
My Broadcast receiver -
public class CallDurationReceiver extends BroadcastReceiver {
// instance variables of sharedpreferences
SharedPreferences mSharedPrefernce;
Editor e;
// String variables for number,date,time,calltype
String number, date, time, calltype;
long startTime, endTime;
#Override
public void onReceive(final Context context, Intent intent) {
Log.v("info", "calls info....");
// initialising the sharedpreferences
mSharedPrefernce = context.getSharedPreferences("MyPref", 0);
e = mSharedPrefernce.edit();
Bundle bundle = intent.getExtras();
if (bundle == null)
return;
// initialising the variables
number = null;
startTime = 0;
endTime = 0;
// getting incoming call details
String state = bundle.getString(TelephonyManager.EXTRA_STATE);
if ((state != null)
&& (state
.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING))) {
Log.v("info", "Phone Ringing..");
number = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
Log.v("info", "Incomng Number: " + number);
calltype = "Incoming";
Time today = new Time(Time.getCurrentTimezone());
today.setToNow();
date = today.monthDay + "-" + (today.month + 1) + "-" + today.year;
time = today.format("%k:%M:%S");
// putting the values into the SharedPreferences
e.putString("number", number);
e.putString("Type", calltype);
e.putString("date", date);
e.putString("time", time);
e.commit();
Toast.makeText(
context,
"Detect Calls sample application\nIncoming number: "
+ number, Toast.LENGTH_SHORT).show();
}
// getting outgoing call details
else if (state == null) {
number = bundle.getString(Intent.EXTRA_PHONE_NUMBER);
Log.v("info", "Outgoing Number: " + number);
calltype = "Outgoing";
Time today = new Time(Time.getCurrentTimezone());
today.setToNow();
date = today.monthDay + "-" + (today.month + 1) + "-" + today.year;
time = today.format("%k:%M:%S");
// putting the values into the SharedPreferences
e.putString("number", number);
e.putString("Type", calltype);
e.putString("date", date);
e.putString("time", time);
e.commit();
Toast.makeText(
context,
"Detect Calls sample application\nOutgoing number: "
+ number, Toast.LENGTH_SHORT).show();
}
// called when the call is answered
else if (state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
Log.v("info", "Call Ansered..");
startTime = System.currentTimeMillis();
e.putLong("start", startTime);
e.commit();
}
// called when the call is ended
else if (state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_IDLE)) {
Log.v("info", "Call Ended..");
String phonenumber=null, type=null, date1=null, time1=null, duration=null;
// getting the values from the SharedPreferences
phonenumber = mSharedPrefernce.getString("number", "");
type = mSharedPrefernce.getString("Type", "");
date1 = mSharedPrefernce.getString("date", "");
time1 = mSharedPrefernce.getString("time", "");
long start=0;
start = mSharedPrefernce.getLong("start", 0);
Log.v("info", "startTime=" + start);
// clearing the SharedPreferences
mSharedPrefernce.edit().clear();
endTime = System.currentTimeMillis();
Log.v("info", "endTime=" + endTime);
long totalTime =0;
totalTime = endTime - start;
DateFormat df = new SimpleDateFormat("HH':'mm':'ss");
df.setTimeZone(TimeZone.getTimeZone("GMT+0"));
duration = df.format(new Date(totalTime));
System.out.println("GOT SOMETHING - "+phonenumber + " " + date1 + " " + time1 + " " + duration + " " + type);
Toast.makeText(context, phonenumber + " " + date1 + " " + time1 + " " + duration + " " + type, Toast.LENGTH_LONG).show();
}
}
}
and the Manifest File -
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.sumasoft.mb.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.sumasoft.mb.HelloService" >
</service>
<receiver android:name=".CallDurationReceiver">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
</application>
I even tried fetching the last outgoing call details from call log but I get the all calls, I just need the last outgoing call.
here is the code -
private String getCallDetails() {
StringBuffer sb = new StringBuffer();
Cursor managedCursor = MainActivity.managedCursor;
int number = managedCursor.getColumnIndex( CallLog.Calls.NUMBER );
int type = managedCursor.getColumnIndex( CallLog.Calls.TYPE );
int date = managedCursor.getColumnIndex( CallLog.Calls.DATE);
int duration = managedCursor.getColumnIndex( CallLog.Calls.DURATION);
sb.append( "Call Details :");
while ( managedCursor.moveToNext() ) {
String phNumber = managedCursor.getString( number );
String callType = managedCursor.getString( type );
String callDate = managedCursor.getString( date );
Date callDayTime = new Date(Long.valueOf(callDate));
String callDuration = managedCursor.getString( duration );
String dir = null;
int dircode = Integer.parseInt( callType );
switch( dircode ) {
case CallLog.Calls.OUTGOING_TYPE:
dir = "OUTGOING";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "INCOMING";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED";
break;
}
sb.append( "\nPhone Number:--- "+phNumber +" \nCall Type:--- "+dir+" \nCall Date:--- "+callDayTime+" \nCall duration in sec :--- "+callDuration );
sb.append("\n----------------------------------");
}
managedCursor.close();
return sb.toString();
}
Thanks in advance.

Categories

Resources