我怎么可以单独在列表视图中的Android呼入呼出记录文件 [英] how can i separate incoming and outgoing call recorded files in listview in android
问题描述
*我开发记录应用程序。因为它会记录所有来电和去电,并正在显示在列表视图这些调用。我想显示传入和传出的录像文件独立的符号。我怎样才能分开吧。请提供解决方案。如果可能的话提供源$ C $ C。 感谢you.am新到Android development.please任何一个可以告诉我的解决方案。
CallBroadCastReceiver.java
公共类CallBroadcastReceiver扩展的BroadcastReceiver
{ 公共无效的onReceive(上下文的背景下,意图意图){ Log.d(CallRecorder,CallBroadcastReceiver:的onReceive了意图:+ intent.toString());
如果(intent.getAction()。等于(Intent.ACTION_NEW_OUTGOING_CALL)){
字符串numberToCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.d(CallRecorder,CallBroadcastReceiver意图有EXTRA_PHONE_NUMBER:+ numberToCall);
}
PhoneListener phoneListener =新PhoneListener(上下文);
TelephonyManager电话=(TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(phoneListener,PhoneStateListener.LISTEN_CALL_STATE);
Log.d(PhoneStateReceiver:的onReceive,设置PhoneStateListener);
}
} *
PhoneListener.java
公共类PhoneListener扩展PhoneStateListener
{ 私人上下文的背景下;
公共PhoneListener(上下文C){
Log.i(CallRecorder,PhoneListener构造);
上下文= C;
}
公共无效onCallStateChanged(INT状态,串incomingNumber)
{
Log.d(CallRecorder,PhoneListener :: onCallStateChanged状态:+状态+incomingNumber:+ incomingNumber);
开关(州){
案例TelephonyManager.CALL_STATE_IDLE:
Log.d(CallRecorder,CALL_STATE_IDLE,回采记录);
布尔停止= context.stopService(新意图(背景下,RecordService.class));
Log.i(CallRecorder,stopService为RecordService返回+停止);
打破;
案例TelephonyManager.CALL_STATE_RINGING:
Log.d(CallRecorder,CALL_STATE_RINGING);
打破;
案例TelephonyManager.CALL_STATE_OFFHOOK:
Log.d(CallRecorder,CALL_STATE_OFFHOOK开始记录);
意图callIntent =新的意图(背景下,RecordService.class);
组件名名称= context.startService(callIntent);
如果(空==名){
Log.e(CallRecorder,startService为RecordService返回null组件名);
} 其他 {
Log.i(CallRecorder,startService返回+ name.flattenToString());
}
打破;
}
}
CallLog.java
公共类CallLoglist扩展活动
{
私人最终字符串变量=CallRecorder;
私人的ListView的fileList = NULL;
//公共静态ArrayAdapter<字符串> fAdapter = NULL;
私人搜索栏搜索栏;
私人的MediaPlayer媒体播放器=新的MediaPlayer();
公共静态的ImageButton暂停按钮;
公众的TextView startTimeField,endTimeField;
AudioManager audioManager;
公共静态最后弦乐STORAGE_LOCATIONN = Environment.getExternalStorageDirectory()+/安卓/数据/ com.callrecorder /收藏夹;
处理器seekHandler =新的处理程序();
对话seekDialog;
私营公用事业utils的;
长totalDuration,currentDuration;
公共静态ImageView的IMG;
的String [] DLIST;
字符串recordlist;
私有列表fAdapter;
ArrayList的<字符串>一个列表;
光标managedCursor;
StringBuffer的某人;
公共字符串名称;
公共串号;
文件源;
CallLoglist CC;
公共静态布尔SS;
字符串phNumber;
公共静态INT一个;
公共静态编辑器编辑;
公共静态共享preferences preF;
公共静态的ArrayList<布尔> ARR =新的ArrayList<布尔>();
私有类CallItemClickListener实现AdapterView.OnItemClickListener {
@覆盖
公共无效onItemClick(适配器视图<>母公司视图中查看,INT位置,长ID)
{
view.showContextMenu();
CharSequence中=(为CharSequence)parent.getItemAtPosition(位置);
Log.w(TAG,CallLog刚刚得到一个项目点击+ S);
//文件F =新的文件(RecordService.DEFAULT_STORAGE_LOCATION +/+ s.toString());
/ *布尔useMediaController = TRUE;
如果(useMediaController){
意图playIntent =新的意图(getApplicationContext(),CallPlayer.class); //Intent.ACTION_VIEW);
开放的我们的uri = Uri.fromFile(F);
playIntent.setData(URI);
startActivity(playIntent);
} 其他 {
playFile(s.toString());
} * /
}
}
@燮pressLint(ShowToast)
@覆盖
公共无效的onCreate(包savedInstanceState)
{
super.onCreate(savedInstanceState);
audioManager =(AudioManager)getSystemService(Context.AUDIO_SERVICE);
的setContentView(R.layout.call_log);
的fileList =(ListView控件)findViewById(R.id.play_file_list);
IMG =(ImageView的)findViewById(R.id.image);
上下文的背景下= getApplicationContext();
setVolumeControlStream(AudioManager.STREAM_MUSIC);
utils的=新的实用程序();
文件DIR =新的文件(RecordService.LOCATION);
DLIST = dir.list();
ALIST =新的ArrayList<字符串>(Arrays.asList(DLIST));
Log.v(豪情,录音文件+ recordlist);
fAdapter =新的列表(此,ALIST);
fileList.setAdapter(fAdapter);
fileList.setOnItemClickListener(新CallItemClickListener());
registerForContextMenu(fileList)中的;
preF = getShared preferences(MM,MODE_PRIVATE);
ED = pref.edit();
/ * ed.putString(RR,R.drawable.arrow);
ed.putString(重,R.drawable.arroww); * /
ed.commit();
////////////////
/ *的String []投影=新的String [] {android.provider.CallLog.Calls.NUMBER,android.provider.CallLog.Calls.DATE,android.provider.CallLog.Calls.CACHED_NAME};
乌里接触= android.provider.CallLog.Calls.CONTENT_URI;
光标managedCursor = managedQuery(联系人,投影,NULL,NULL,android.provider.CallLog.Calls.DATE +ASC);
getColumnData(managedCursor);
}
私人无效getColumnData(光标CUR){
尝试{
如果(cur.moveToFirst()){
长日期;
INT名称列= cur.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
INT numberColumn = cur.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
INT dateColumn = cur.getColumnIndex(android.provider.CallLog.Calls.DATE);
的System.out.println(阅读呼叫详细:);
做 {
名称= cur.getString(名称列);
数= cur.getString(numberColumn);
日期= cur.getLong(dateColumn);
的System.out.println(数字+:+新的日期(日期)+:+姓名);
}而(cur.moveToNext());
}
}
最后{
cur.close();
} * /
}
公共无效onCreateContextMenu(文本菜单菜单,视图V,
ContextMenuInfo menuInfo){
// TODO自动生成方法存根
super.onCreateContextMenu(菜单,V,menuInfo);
MenuInflater米= getMenuInflater();
m.inflate(R.menu.nn,菜单);
}
@燮pressLint({ShowToast,SdCardPath})
@覆盖
公共布尔onContextItemSelected(菜单项项){
// TODO自动生成方法存根
AdapterContextMenuInfo信息=(AdapterContextMenuInfo)item.getMenuInfo();
INT指数= info.position;
recordlist = alist.get(指数);
// PP = DLIST。
开关(item.getItemId()){
案例R.id.play:
seekDialog =新的对话框(本);
seekDialog.setTitle(玩);
seekDialog.setContentView(R.layout.dialog);
startTimeField =(TextView中)seekDialog.findViewById(R.id.textView1);
endTimeField =(TextView中)seekDialog.findViewById(R.id.textView2);
暂停按钮=(的ImageButton)seekDialog.findViewById(R.id.imageButton2);
搜索栏=(搜索栏)seekDialog.findViewById(R.id.seek);
seekDialog.show();
Log.v(文件,+指数);
如果(媒体播放器!= NULL){
mediaPlayer.release();
}
/*mediaPlayer=MediaPlayer.create(this,Uri.parse(Environment.getExternalStorageDirectory()。getAbsolutePath()
+/Android/data/com.callrecorder/recordings/+ pathh)); * /
媒体播放器= MediaPlayer.create(这一点,Uri.parse(Environment.getExternalStorageDirectory()。getAbsolutePath()
+/Android/data/com.callrecorder/recordings/+ recordlist));
mediaPlayer.start();
seekUpdation();
totalDuration = mediaPlayer.getDuration();
seekbar.setMax((INT)totalDuration);
pauseButton.setOnClickListener(新OnClickListener(){
@覆盖
公共无效的onClick(视图v){
// TODO自动生成方法存根
如果(mediaPlayer.isPlaying())
{
mediaPlayer.pause();
pauseButton.setImageResource(R.drawable.play);
Toast.makeText(getApplicationContext(),暂停,1000).show();
}
其他
{
mediaPlayer.start();
pauseButton.setImageResource(R.drawable.pause);
Toast.makeText(getApplicationContext(),玩,1000).show();
}
}
});
seekDialog.setOnDismissListener(新OnDismissListener(){
@覆盖
公共无效onDismiss(DialogInterface对话){
// TODO自动生成方法存根
mediaPlayer.release();
}
});
seekbar.setOnSeekBarChangeListener(新OnSeekBarChangeListener(){
@覆盖
公共无效onStopTrackingTouch(搜索栏搜索栏){
// TODO自动生成方法存根
}
@覆盖
公共无效onStartTrackingTouch(搜索栏搜索栏){
// TODO自动生成方法存根
}
@覆盖
公共无效onProgressChanged(搜索栏搜索栏,INT进步,
布尔FROMUSER){
// TODO自动生成方法存根
如果(FROMUSER)
{
mediaPlayer.pause();
seekbar.setProgress(mediaPlayer.getCurrentPosition());
seekbar.setMax(mediaPlayer.getDuration());
mediaPlayer.seekTo(进度);
mediaPlayer.start();
pauseButton.setImageResource(R.drawable.pause);
seekUpdation();
}
}
});
打破;
案例R.id.delete:
Toast.makeText(getApplicationContext(),删除,1000).show();
//新的文件(Environment.getExternalStorageDirectory()+/ callrecorder /+ pathh).delete();
新的文件(Environment.getExternalStorageDirectory()getAbsolutePath()+/Android/data/com.callrecorder/recordings/+ recordlist。).delete();
alist.remove(指数);
alist.clear();
fAdapter.notifyDataSetChanged();
fAdapter.notifyDataSetInvalidated();
打破;
案例R.id.favorites:
Toast.makeText(getApplicationContext(),favouraties,1000).show();
来源=新的文件(Environment.getExternalStorageDirectory()+/Android/data/com.callrecorder/recordings/+ recordlist);
文件DIR =新的文件(STORAGE_LOCATIONN);
如果(!dir.exists())
{
尝试 {
dir.mkdir();
}赶上(例外五){
// TODO:处理异常
}
}
尝试 {
InputStream的时间=新的FileInputStream(源);
的OutputStream OUT =新的FileOutputStream(STORAGE_LOCATIONN +/+ recordlist);
//传输的字节从以出
byte []的BUF =新的字节[1024];
INT LEN;
而((LEN = in.read(BUF))大于0){
out.write(BUF,0,的len);
}
附寄();
out.close();
}赶上(例外五){
// TODO:处理异常
Log.v(copyyy,errorrrrr);
}
source.delete();
alist.remove(指数);
fAdapter.notifyDataSetChanged();
fAdapter.notifyDataSetInvalidated();
打破;
默认:
}
返回super.onContextItemSelected(项目);
}
可运行的银行经营=新的Runnable(){
@覆盖公共无效的run(){
尝试 {
seekUpdation();
}赶上(例外五){
// TODO:处理异常
}
尝试 {
totalDuration = mediaPlayer.getDuration();
currentDuration = mediaPlayer.getCurrentPosition();
//显示总持续时间
endTimeField.setText(+ utils.milliSecondsToTimer(totalDuration));
//显示的时间内完成演奏
startTimeField.setText(+ utils.milliSecondsToTimer(currentDuration));
seekbar.setProgress((INT)currentDuration); //移动搜索栏
//更新进度条
/ * INT进度=(INT)(utils.getProgressPercentage(currentDuration,totalDuration));
//Log.d("Progress,+进展);
seekbar.setProgress(进度); * /
// seekHandler.postDelayed(此,100);
}赶上(例外五){
// TODO:处理异常
}
}
};
公共无效seekUpdation(){
//seekbar.setProgress(mediaPlayer.getCurrentPosition());
//mHandler.postDelayed(mUpdateTimeTask,100);
seekHandler.postDelayed(银行经营,1000);
}
公共无效的OnStart()
{
super.onStart();
Log.i(TAG,CallLog ONSTART);
}
公共无效onRestart()
{
super.onRestart();
Log.i(TAG,CallLog onRestart);
}
/ *公共无效onResume()
{
super.onResume();
//Log.i(TAG,CallLog onResume即将再次载入记录列表,做这项工作?);
loadRecordingsFromDir();
} * /
@覆盖
保护无效的onDestroy(){
/ *如果(NULL!=媒体播放器){
mediaPlayer.release();
} * /
super.onDestroy();
如果(媒体播放器!= NULL){
//mediaPlayer.stop();
mediaPlayer.release();
媒体播放器= NULL;
}
}
///////////////////////////////////////////
私有类列表扩展了BaseAdapter
{
私人CallLoglist callLog;
私人的ArrayList<字符串>一个列表;
公示名单(CallLoglist callLog,ArrayList的<字符串> ALIST){
// TODO自动生成构造函数存根
this.callLog = callLog;
this.alist = ALIST;
}
@覆盖
公众诠释getCount将(){
// TODO自动生成方法存根
返回alist.size();
}
@覆盖
公共对象的getItem(INT位置){
// TODO自动生成方法存根
返回null;
}
@覆盖
众长getItemId(INT位置){
// TODO自动生成方法存根
返回的位置;
}
@覆盖
公共查看getView(INT位置,视图V,ViewGroup中父){
// TODO自动生成方法存根
LayoutInflater充气=(LayoutInflater)getApplicationContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
V = inflater.inflate(R.layout.calllist,父母,假);
TextView中的TextView =(TextView中)v.findViewById(R.id.text);
ImageView的ImageView的=(ImageView的)v.findViewById(R.id.image);
textView.setText(alist.get(位置));
串AA = pref.getString(RR,);
串峰dd = pref.getString(重,);
如果(aa.equals(0)){
imageView.setImageResource(R.drawable.arrow);
}
其他 {
imageView.setImageResource(R.drawable.arroww);
}
//imageView.setImageResource(R.drawable.arrow);
// TextView的文字=(TextView的)v.findViewById(R.id.namee);
/*if(arr.get(position))
{
imageView.setImageResource(R.drawable.arrow);
}
其他 {
imageView.setImageResource(R.drawable.arroww);
} * /
返回伏;
}
}
Recordservice.java
*公共类RecordService
延伸服务
实现MediaRecorder.OnInfoListener,MediaRecorder.OnErrorListener
{
私有静态最后字符串变量=CallRecorder;
//公共静态最后弦乐DEFAULT_STORAGE_LOCATION =/ SD卡/ callrecorder;
公共静态最后弦乐DEFAULT_STORAGE_LOCATION =/ SD卡/安卓/数据/ com.callrecorder /录音;
私有静态最终诠释RECORDING_NOTIFICATION_ID = 1;
私人MediaRecorder记录= NULL;
私人布尔isRecording = FALSE;
私人字符串传入的;
私人吐司的大小;
公共静态文件记录= NULL ;;
意向意图;
私人文件makeOutputFile(共享preferences preFS)
{
文件DIR =新的文件(DEFAULT_STORAGE_LOCATION);
//测试目录是否存在和可写
如果(!dir.exists()){
尝试 {
dir.mkdirs();
}赶上(例外五){
Log.e(CallRecorder,RecordService:makeOutputFile无法创建目录+方向+:+ E);
吐司T = Toast.makeText(getApplicationContext(),CallRecorder无法创建目录+方向+来存储录音:+ E,Toast.LENGTH_LONG);
t.show();
返回null;
}
} 其他 {
如果(!dir.canWrite()){
Log.e(TAG,RecordService:makeOutputFile没有写权限的目录:+方向);
吐司T = Toast.makeText(getApplicationContext(),CallRecorder没有该目录的目录的写权限+方向+来存储录音,Toast.LENGTH_LONG);
t.show();
返回null;
}
}
字符串preFIX =CAL;
//字符串preFIX = PhoneListener.incoming;
INT audiosource =的Integer.parseInt(prefs.getString(preferences preF_AUDIO_SOURCE,1));
// preFIX + = - + audiosource;
preFIX + =+ PhoneListener.incoming;
字符串后缀=;
INT AudioFormat的=的Integer.parseInt(prefs.getString(preferences preF_AUDIO_FORMAT,1));
开关(AudioFormat的){
案例MediaRecorder.OutputFormat.THREE_GPP:
后缀=.3gpp;
打破;
案例MediaRecorder.OutputFormat.MPEG_4:
后缀=.MPG;
打破;
案例MediaRecorder.OutputFormat.RAW_AMR:
后缀=.AMR;
打破;
}
尝试 {
返回File.createTempFile(preFIX,后缀,DIR);
}赶上(IOException异常E){
Log.e(CallRecorder,RecordService:makeOutputFile无法创建临时文件+方向+:+ E);
吐司T = Toast.makeText(getApplicationContext(),CallRecorder无法创建临时文件+方向+:+ E,Toast.LENGTH_LONG);
t.show();
返回null;
}
}
公共无效的onCreate()
{
super.onCreate();
记录=新MediaRecorder();
Log.i(CallRecorder,的onCreate创建MediaRecorder对象);
}
@燮pressLint(ShowToast)
公共无效ONSTART(意向意图,诠释startId){
Log.i(CallRecorder,RecordService:onStartCommand时调用isRecording:+ isRecording);
如果(isRecording)回报;
上下文C = getApplicationContext();
共享preferences preFS = preferenceManager.getDefaultShared preferences(C);
布尔shouldRecord = prefs.getBoolean(preferences preF_RECORD_CALLS,假的。);
如果(!shouldRecord){
Log.i(CallRecord,RecordService:onStartCommand用preF_RECORD_CALLS假的,没有记录);
返回;
}
INT audiosource =的Integer.parseInt(prefs.getString(preferences preF_AUDIO_SOURCE,1));
INT AudioFormat的=的Integer.parseInt(prefs.getString(preferences preF_AUDIO_FORMAT,1));
记录= makeOutputFile(preFS);
如果(记录== NULL){
记录= NULL;
返回; //返回0;
}
Log.i(CallRecorder,RecordService将CONFIG MediaRecorder与audiosource:+ audiosource +AudioFormat的:+ AudioFormat的);
尝试 {
recorder.reset();
recorder.setAudioSource(audiosource);
Log.d(CallRecorder,设置audiosource+ audiosource);
recorder.setOutputFormat(AudioFormat的);
Log.d(CallRecorder,设置输出+ AudioFormat的);
recorder.setAudioEn codeR(MediaRecorder.AudioEn coder.DEFAULT);
Log.d(CallRecorder,设置连接codeR默认);
recorder.setOutputFile(recording.getAbsolutePath());
Log.d(CallRecorder,设置文件:+录音);
recorder.setOnInfoListener(本);
recorder.setOnErrorListener(本);
尝试 {
。录音机prepare();
}赶上(java.io.IOException异常E){
Log.e(CallRecorder,RecordService:ONSTART()IOException异常试图记录prepare()\ñ。);
吐司T = Toast.makeText(getApplicationContext(),CallRecorder无法启动录音:+ E,Toast.LENGTH_LONG);
t.show();
记录= NULL;
返回; //返回0; // START_STICKY;
}
Log.d(CallRecorder,录音机prepare()返回);
recorder.start();
isRecording = TRUE;
Log.i(CallRecorder,recorder.start()返回);
updateNotification(真正的);
}赶上(java.lang.Exception的E){
吐司T = Toast.makeText(getApplicationContext(),CallRecorder无法启动录音:+ E,Toast.LENGTH_LONG);
t.show();
Log.e(CallRecorder,RecordService:ONSTART陷入意外的异常,E);
记录= NULL;
}
返回;
}
公共无效的onDestroy()
{
super.onDestroy();
如果(NULL!=记录器){
Log.i(CallRecorder,RecordService:的onDestroy调用recorder.release());
isRecording = FALSE;
recorder.release();
长长度= recording.length();
长度=长度/ 1024;
Log.v(呼叫,pathh+ recording.getAbsolutePath()+长度+KB);
如果(长度== 0)
{
Log.v(sizeeee,设置);
Toast.makeText(getApplicationContext(),更改音频源设置,Toast.LENGTH_LONG).show();
recording.delete();
Log.v(文件,删除);
}
吐司T = Toast.makeText(getApplicationContext(),CallRecorder录完呼吁+录音,Toast.LENGTH_LONG);
t.show();
}
updateNotification(假);
}
//方法来处理绑定的服务
公众的IBinder onBind(意向意图)
{
返回null;
}
公共布尔onUnbind(意向意图)
{
返回false;
}
公共无效onRebind(意向意图)
{
}
私人无效updateNotification(布尔状态)
{
上下文C = getApplicationContext();
共享preferences preFS = preferenceManager.getDefaultShared preferences(C);
字符串NS = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager =(NotificationManager)getSystemService(NS);
如果(状态){
INT图标= R.drawable.ic_launcher;
CharSequence的tickerText =录音电话+ prefs.getString(preferences preF_AUDIO_SOURCE,1);
// CharSequence的tickerText =录音电话+ prefs.getString(preferences preF_AUDIO_SOURCE,1);
时长= System.currentTimeMillis的();
//通知的通知=新的通知(图标,tickerText时);
通知通知=新的通知(图标,tickerText时);
上下文的背景下= getApplicationContext();
CharSequence的contentTitle =CallRecorder状态;
CharSequence的contentText =录音电话......;
意图notificationIntent =新的意图(这一点,RecordService.class);
PendingIntent contentIntent = PendingIntent.getActivity(此,0,notificationIntent,0);
notification.setLatestEventInfo(背景下,contentTitle,contentText,contentIntent);
mNotificationManager.notify(RECORDING_NOTIFICATION_ID,通知);
} 其他 {
mNotificationManager.cancel(RECORDING_NOTIFICATION_ID);
}
}
// MediaRecorder.OnInfoListener
公共无效onInfo(MediaRecorder先生,诠释了什么,整型附加)
{
Log.i(CallRecorder,RecordService得到MediaRecorder onInfo回调什么:+什么+额外+另计);
isRecording = FALSE;
}
// MediaRecorder.OnErrorListener
公共无效onerror的(MediaRecorder先生,诠释了什么,整型附加)
{
Log.e(CallRecorder,RecordService得到MediaRecorder的onError回调什么:+什么+额外+另计);
isRecording = FALSE;
mr.release();
}
} *
您必须营造出的的BroadcastReceiver 的。该接收器检测如果呼叫传入或传出。在那里,你可以记录您的来电。使用TelephonyManager类。而在清单中添加权限。
在连结与源 - code下载一个基本描述:的 的http://www.devlper.com/2010/08/detecting-incoming-and-outgoing-calls-in-android/
如果你的工作,你只需要创建一个Dictionary(HashMap中)。在那里,你可以设置字典键保存号码并传入或传出呼叫的键值。
获取熟悉自定义的ListView创建具有图像的ListView。的 的http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/
创建2图像,传入和传出。 LOPP通过你的字典,并设置图像的权利。
问候
*I am developing recording application. In that it will record all incoming and outgoing calls and am displayed these calls in listview. I want to display separate symbols for incoming and outgoing recording files. How can i separate it. please provide solution. If possible provide source code. thank you.am new to android development.please can any one tell me the solution..
CallBroadCastReceiver.java
public class CallBroadcastReceiver extends BroadcastReceiver
{ public void onReceive(Context context, Intent intent) { Log.d("CallRecorder", "CallBroadcastReceiver:onReceive got Intent: " + intent.toString());
if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
String numberToCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.d("CallRecorder", "CallBroadcastReceiver intent has EXTRA_PHONE_NUMBER: " + numberToCall);
}
PhoneListener phoneListener = new PhoneListener(context);
TelephonyManager telephony = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
Log.d("PhoneStateReceiver:onReceive", "set PhoneStateListener");
}
}*
PhoneListener.java
public class PhoneListener extends PhoneStateListener
{ private Context context;
public PhoneListener(Context c) {
Log.i("CallRecorder", "PhoneListener constructor");
context = c;
}
public void onCallStateChanged (int state, String incomingNumber)
{
Log.d("CallRecorder", "PhoneListener::onCallStateChanged state:" + state + " incomingNumber:" + incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
Log.d("CallRecorder", "CALL_STATE_IDLE, stoping recording");
Boolean stopped = context.stopService(new Intent(context, RecordService.class));
Log.i("CallRecorder", "stopService for RecordService returned " + stopped);
break;
case TelephonyManager.CALL_STATE_RINGING:
Log.d("CallRecorder", "CALL_STATE_RINGING");
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d("CallRecorder", "CALL_STATE_OFFHOOK starting recording");
Intent callIntent = new Intent(context, RecordService.class);
ComponentName name = context.startService(callIntent);
if (null == name) {
Log.e("CallRecorder", "startService for RecordService returned null ComponentName");
} else {
Log.i("CallRecorder", "startService returned " + name.flattenToString());
}
break;
}
}
CallLog.java
public class CallLoglist extends Activity
{
private final String TAG = "CallRecorder";
private ListView fileList = null;
//public static ArrayAdapter<String> fAdapter = null;
private SeekBar seekbar;
private MediaPlayer mediaPlayer=new MediaPlayer();
public static ImageButton pauseButton;
public TextView startTimeField,endTimeField;
AudioManager audioManager;
public static final String STORAGE_LOCATIONN = Environment.getExternalStorageDirectory()+"/Android/data/com.callrecorder/favourites";
Handler seekHandler = new Handler();
Dialog seekDialog;
private Utilities utils;
long totalDuration,currentDuration;
public static ImageView img;
String[] dlist;
String recordlist;
private list fAdapter;
ArrayList<String> alist;
Cursor managedCursor;
StringBuffer sb;
public String name;
public String number;
File source;
CallLoglist cc;
public static boolean ss;
String phNumber;
public static int a;
public static Editor ed;
public static SharedPreferences pref;
public static ArrayList<Boolean> arr= new ArrayList<Boolean>();
private class CallItemClickListener implements AdapterView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
view.showContextMenu();
CharSequence s = (CharSequence)parent.getItemAtPosition(position);
Log.w(TAG, "CallLog just got an item clicked: " + s);
//File f = new File(RecordService.DEFAULT_STORAGE_LOCATION + "/" + s.toString());
/*boolean useMediaController = true;
if (useMediaController) {
Intent playIntent = new Intent(getApplicationContext(), CallPlayer.class); //Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(f);
playIntent.setData(uri);
startActivity(playIntent);
} else {
playFile(s.toString());
}*/
}
}
@SuppressLint("ShowToast")
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
setContentView(R.layout.call_log);
fileList = (ListView)findViewById(R.id.play_file_list);
img=(ImageView)findViewById(R.id.image);
Context context = getApplicationContext();
setVolumeControlStream(AudioManager.STREAM_MUSIC);
utils=new Utilities();
File dir = new File(RecordService.LOCATION);
dlist = dir.list();
alist=new ArrayList<String>(Arrays.asList(dlist));
Log.v("fille", "recording file" +recordlist);
fAdapter=new list(this,alist);
fileList.setAdapter(fAdapter);
fileList.setOnItemClickListener(new CallItemClickListener());
registerForContextMenu(fileList);
pref=getSharedPreferences("mm", MODE_PRIVATE);
ed=pref.edit();
/* ed.putString("rr", "R.drawable.arrow");
ed.putString("re", "R.drawable.arroww");*/
ed.commit();
////////////////
/*String[] projection = new String[] {android.provider.CallLog.Calls.NUMBER, android.provider.CallLog.Calls.DATE, android.provider.CallLog.Calls.CACHED_NAME};
Uri contacts = android.provider.CallLog.Calls.CONTENT_URI;
Cursor managedCursor = managedQuery(contacts, projection, null, null, android.provider.CallLog.Calls.DATE + " ASC");
getColumnData(managedCursor);
}
private void getColumnData(Cursor cur){
try{
if (cur.moveToFirst()) {
long date;
int nameColumn = cur.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
int numberColumn = cur.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
int dateColumn = cur.getColumnIndex(android.provider.CallLog.Calls.DATE);
System.out.println("Reading Call Details: ");
do {
name = cur.getString(nameColumn);
number = cur.getString(numberColumn);
date = cur.getLong(dateColumn);
System.out.println(number + ":"+ new Date(date) +":"+name);
} while (cur.moveToNext());
}
}
finally{
cur.close();
}*/
}
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
// TODO Auto-generated method stub
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater m = getMenuInflater();
m.inflate(R.menu.nn, menu);
}
@SuppressLint({ "ShowToast", "SdCardPath" })
@Override
public boolean onContextItemSelected(MenuItem item) {
// TODO Auto-generated method stub
AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo();
int index=info.position;
recordlist=alist.get(index);
//pp=dlist.
switch(item.getItemId()){
case R.id.play:
seekDialog = new Dialog(this);
seekDialog.setTitle("play");
seekDialog.setContentView(R.layout.dialog);
startTimeField=(TextView)seekDialog.findViewById(R.id.textView1);
endTimeField=(TextView)seekDialog.findViewById(R.id.textView2);
pauseButton = (ImageButton)seekDialog.findViewById(R.id.imageButton2);
seekbar = (SeekBar)seekDialog.findViewById(R.id.seek);
seekDialog.show();
Log.v("file", ""+index);
if (mediaPlayer != null) {
mediaPlayer.release();
}
/*mediaPlayer=MediaPlayer.create(this, Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/Android/data/com.callrecorder/recordings/" +pathh ));*/
mediaPlayer=MediaPlayer.create(this, Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/Android/data/com.callrecorder/recordings/" +recordlist));
mediaPlayer.start();
seekUpdation();
totalDuration=mediaPlayer.getDuration();
seekbar.setMax((int) totalDuration);
pauseButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(mediaPlayer.isPlaying())
{
mediaPlayer.pause();
pauseButton.setImageResource(R.drawable.play);
Toast.makeText(getApplicationContext(), "pause", 1000).show();
}
else
{
mediaPlayer.start();
pauseButton.setImageResource(R.drawable.pause);
Toast.makeText(getApplicationContext(), "play", 1000).show();
}
}
});
seekDialog.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
// TODO Auto-generated method stub
mediaPlayer.release();
}
});
seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
if(fromUser)
{
mediaPlayer.pause();
seekbar.setProgress(mediaPlayer.getCurrentPosition());
seekbar.setMax(mediaPlayer.getDuration());
mediaPlayer.seekTo(progress);
mediaPlayer.start();
pauseButton.setImageResource(R.drawable.pause);
seekUpdation();
}
}
});
break;
case R.id.delete:
Toast.makeText(getApplicationContext(), "delete", 1000).show();
//new File(Environment.getExternalStorageDirectory()+"/callrecorder/" + pathh).delete();
new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/com.callrecorder/recordings/" +recordlist).delete();
alist.remove(index);
alist.clear();
fAdapter.notifyDataSetChanged();
fAdapter.notifyDataSetInvalidated();
break;
case R.id.favorites:
Toast.makeText(getApplicationContext(), "favouraties", 1000).show();
source=new File(Environment.getExternalStorageDirectory() + "/Android/data/com.callrecorder/recordings/" +recordlist);
File dir=new File(STORAGE_LOCATIONN);
if(!dir.exists())
{
try {
dir.mkdir();
} catch (Exception e) {
// TODO: handle exception
}
}
try {
InputStream in=new FileInputStream(source);
OutputStream out = new FileOutputStream(STORAGE_LOCATIONN+"/"+recordlist);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0){
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (Exception e) {
// TODO: handle exception
Log.v("copyyy", "errorrrrr");
}
source.delete();
alist.remove(index);
fAdapter.notifyDataSetChanged();
fAdapter.notifyDataSetInvalidated();
break;
default:
}
return super.onContextItemSelected(item);
}
Runnable runn = new Runnable() {
@Override public void run() {
try {
seekUpdation();
} catch (Exception e) {
// TODO: handle exception
}
try {
totalDuration = mediaPlayer.getDuration();
currentDuration = mediaPlayer.getCurrentPosition();
// Displaying Total Duration time
endTimeField.setText(""+utils.milliSecondsToTimer(totalDuration));
// Displaying time completed playing
startTimeField.setText(""+utils.milliSecondsToTimer(currentDuration));
seekbar.setProgress((int) currentDuration); //move seek bar
// Updating progress bar
/* int progress = (int)(utils.getProgressPercentage(currentDuration,totalDuration));
//Log.d("Progress", ""+progress);
seekbar.setProgress(progress);*/
// seekHandler.postDelayed(this, 100);
} catch (Exception e) {
// TODO: handle exception
}
}
};
public void seekUpdation() {
//seekbar.setProgress(mediaPlayer.getCurrentPosition());
//mHandler.postDelayed(mUpdateTimeTask, 100);
seekHandler.postDelayed(runn, 1000);
}
public void onStart()
{
super.onStart();
Log.i(TAG, "CallLog onStart");
}
public void onRestart()
{
super.onRestart();
Log.i(TAG, "CallLog onRestart");
}
/*public void onResume()
{
super.onResume();
//Log.i(TAG, "CallLog onResume about to load recording list again, does this work?");
loadRecordingsFromDir();
}*/
@Override
protected void onDestroy() {
/*if(null!=mediaPlayer){
mediaPlayer.release();
}*/
super.onDestroy();
if(mediaPlayer!=null){
//mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
}
///////////////////////////////////////////
private class list extends BaseAdapter
{
private CallLoglist callLog;
private ArrayList<String> alist;
public list(CallLoglist callLog, ArrayList<String> alist) {
// TODO Auto-generated constructor stub
this.callLog=callLog;
this.alist=alist;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return alist.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View v, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater)getApplicationContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.calllist, parent, false);
TextView textView = (TextView)v.findViewById(R.id.text);
ImageView imageView = (ImageView)v.findViewById(R.id.image);
textView.setText(alist.get(position));
String aa=pref.getString("rr", "");
String dd=pref.getString("re", "");
if (aa.equals("0")) {
imageView.setImageResource(R.drawable.arrow);
}
else {
imageView.setImageResource(R.drawable.arroww);
}
//imageView.setImageResource(R.drawable.arrow);
//TextView text=(TextView)v.findViewById(R.id.namee);
/*if(arr.get(position))
{
imageView.setImageResource(R.drawable.arrow);
}
else {
imageView.setImageResource(R.drawable.arroww);
}*/
return v;
}
}
Recordservice.java
*public class RecordService
extends Service
implements MediaRecorder.OnInfoListener, MediaRecorder.OnErrorListener
{
private static final String TAG = "CallRecorder";
//public static final String DEFAULT_STORAGE_LOCATION = "/sdcard/callrecorder";
public static final String DEFAULT_STORAGE_LOCATION="/sdcard/Android/data/com.callrecorder/recordings";
private static final int RECORDING_NOTIFICATION_ID = 1;
private MediaRecorder recorder = null;
private boolean isRecording = false;
private String incoming;
private Toast size;
public static File recording = null;;
Intent intent;
private File makeOutputFile (SharedPreferences prefs)
{
File dir = new File(DEFAULT_STORAGE_LOCATION);
// test dir for existence and writeability
if (!dir.exists()) {
try {
dir.mkdirs();
} catch (Exception e) {
Log.e("CallRecorder", "RecordService:makeOutputFile unable to create directory " + dir + ": " + e);
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder was unable to create the directory " + dir + " to store recordings: " + e, Toast.LENGTH_LONG);
t.show();
return null;
}
} else {
if (!dir.canWrite()) {
Log.e(TAG, "RecordService:makeOutputFile does not have write permission for directory: " + dir);
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder does not have write permission for the directory directory " + dir + " to store recordings", Toast.LENGTH_LONG);
t.show();
return null;
}
}
String prefix = "cal";
//String prefix= PhoneListener.incoming;
int audiosource = Integer.parseInt(prefs.getString(Preferences.PREF_AUDIO_SOURCE, "1"));
//prefix += "-" + audiosource ;
prefix+= "" +PhoneListener.incoming;
String suffix = "";
int audioformat = Integer.parseInt(prefs.getString(Preferences.PREF_AUDIO_FORMAT, "1"));
switch (audioformat) {
case MediaRecorder.OutputFormat.THREE_GPP:
suffix = ".3gpp";
break;
case MediaRecorder.OutputFormat.MPEG_4:
suffix = ".mpg";
break;
case MediaRecorder.OutputFormat.RAW_AMR:
suffix = ".amr";
break;
}
try {
return File.createTempFile(prefix, suffix, dir);
} catch (IOException e) {
Log.e("CallRecorder", "RecordService:makeOutputFile unable to create temp file in " + dir + ": " + e);
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder was unable to create temp file in " + dir + ": " + e, Toast.LENGTH_LONG);
t.show();
return null;
}
}
public void onCreate()
{
super.onCreate();
recorder = new MediaRecorder();
Log.i("CallRecorder", "onCreate created MediaRecorder object");
}
@SuppressLint("ShowToast")
public void onStart(Intent intent, int startId) {
Log.i("CallRecorder", "RecordService:onStartCommand called while isRecording:" + isRecording);
if (isRecording) return;
Context c = getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
Boolean shouldRecord = prefs.getBoolean(Preferences.PREF_RECORD_CALLS, false);
if (!shouldRecord) {
Log.i("CallRecord", "RecordService:onStartCommand with PREF_RECORD_CALLS false, not recording");
return;
}
int audiosource = Integer.parseInt(prefs.getString(Preferences.PREF_AUDIO_SOURCE, "1"));
int audioformat = Integer.parseInt(prefs.getString(Preferences.PREF_AUDIO_FORMAT, "1"));
recording = makeOutputFile(prefs);
if (recording == null) {
recorder = null;
return; //return 0;
}
Log.i("CallRecorder", "RecordService will config MediaRecorder with audiosource: " + audiosource + " audioformat: " + audioformat);
try {
recorder.reset();
recorder.setAudioSource(audiosource);
Log.d("CallRecorder", "set audiosource " + audiosource);
recorder.setOutputFormat(audioformat);
Log.d("CallRecorder", "set output " + audioformat);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
Log.d("CallRecorder", "set encoder default");
recorder.setOutputFile(recording.getAbsolutePath());
Log.d("CallRecorder", "set file:" + recording);
recorder.setOnInfoListener(this);
recorder.setOnErrorListener(this);
try {
recorder.prepare();
} catch (java.io.IOException e) {
Log.e("CallRecorder", "RecordService:onStart() IOException attempting recorder.prepare()\n");
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder was unable to start recording: " + e, Toast.LENGTH_LONG);
t.show();
recorder = null;
return; //return 0; //START_STICKY;
}
Log.d("CallRecorder", "recorder.prepare() returned");
recorder.start();
isRecording = true;
Log.i("CallRecorder", "recorder.start() returned");
updateNotification(true);
} catch (java.lang.Exception e) {
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder was unable to start recording: " + e, Toast.LENGTH_LONG);
t.show();
Log.e("CallRecorder", "RecordService:onStart caught unexpected exception", e);
recorder = null;
}
return;
}
public void onDestroy()
{
super.onDestroy();
if (null != recorder) {
Log.i("CallRecorder", "RecordService:onDestroy calling recorder.release()");
isRecording = false;
recorder.release();
long length=recording.length();
length=length/1024;
Log.v("call", "pathh" +recording.getAbsolutePath() + length + "KB" );
if(length==0)
{
Log.v("sizeeee", "settings");
Toast.makeText(getApplicationContext(), "change the audio source settings", Toast.LENGTH_LONG).show();
recording.delete();
Log.v("file", "delete");
}
Toast t = Toast.makeText(getApplicationContext(), "CallRecorder finished recording call to" + recording, Toast.LENGTH_LONG);
t.show();
}
updateNotification(false);
}
// methods to handle binding the service
public IBinder onBind(Intent intent)
{
return null;
}
public boolean onUnbind(Intent intent)
{
return false;
}
public void onRebind(Intent intent)
{
}
private void updateNotification(Boolean status)
{
Context c = getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
if (status) {
int icon = R.drawable.ic_launcher;
CharSequence tickerText = "Recording call " + prefs.getString(Preferences.PREF_AUDIO_SOURCE, "1");
//CharSequence tickerText = "Recording call " + prefs.getString(Preferences.PREF_AUDIO_SOURCE, "1");
long when = System.currentTimeMillis();
//Notification notification = new Notification(icon, tickerText, when);
Notification notification=new Notification(icon,tickerText,when);
Context context = getApplicationContext();
CharSequence contentTitle = "CallRecorder Status";
CharSequence contentText = "Recording call...";
Intent notificationIntent = new Intent(this, RecordService.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
mNotificationManager.notify(RECORDING_NOTIFICATION_ID, notification);
} else {
mNotificationManager.cancel(RECORDING_NOTIFICATION_ID);
}
}
// MediaRecorder.OnInfoListener
public void onInfo(MediaRecorder mr, int what, int extra)
{
Log.i("CallRecorder", "RecordService got MediaRecorder onInfo callback with what: " + what + " extra: " + extra);
isRecording = false;
}
// MediaRecorder.OnErrorListener
public void onError(MediaRecorder mr, int what, int extra)
{
Log.e("CallRecorder", "RecordService got MediaRecorder onError callback with what: " + what + " extra: " + extra);
isRecording = false;
mr.release();
}
}*
You would have to create a a broadcastreceiver. The receiver detects if an call is incoming or outgoing. There you can record your calls. Use TelephonyManager Class. And add permissions in the manifest.
In the link is a basic description with source-code download: http://www.devlper.com/2010/08/detecting-incoming-and-outgoing-calls-in-android/
If you get that working, you just would have to create a Dictionary(HashMap). There you could set the dictionary-key to save numbers and a key-value for incoming or outgoing calls.
Get familiar with custom ListView to create a ListView with an image. http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/
Create 2 images, incoming and outgoing. Lopp through your dictionary and set the images right.
Greets
这篇关于我怎么可以单独在列表视图中的Android呼入呼出记录文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!