enhanced history tab
This commit is contained in:
parent
b372bdca49
commit
1dd0a7285d
6 changed files with 135 additions and 60 deletions
|
@ -1,44 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?> <!-- from Android Layout Tricks #1 -->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="?android:attr/listPreferredItemHeight"
|
||||
android:padding="6dip">
|
||||
<ImageView
|
||||
android:id="@+id/history_cell_icon"
|
||||
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginRight="6dip"
|
||||
|
||||
android:src="@drawable/icon" />
|
||||
android:layout_width="fill_parent" android:layout_height="?android:attr/listPreferredItemHeight"
|
||||
android:padding="6dip">
|
||||
<FrameLayout
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentBottom="true" android:layout_marginRight="6dip"
|
||||
android:id="@+id/history_cell_icon">
|
||||
<ImageView android:id="@+id/history_cell_icon_in"
|
||||
android:layout_width="wrap_content" android:layout_height="fill_parent"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentBottom="true" android:layout_marginRight="6dip"
|
||||
android:src="@drawable/in_call" android:scaleType="centerInside"/>
|
||||
<ImageView android:id="@+id/history_cell_icon_out"
|
||||
android:layout_width="wrap_content" android:layout_height="fill_parent"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentBottom="true" android:layout_marginRight="6dip"
|
||||
android:src="@drawable/out_call" android:scaleType="centerInside"/>
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/history_cell_second_line"
|
||||
<TextView android:id="@+id/history_cell_second_line"
|
||||
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="26dip"
|
||||
|
||||
android:layout_toRightOf="@id/history_cell_icon"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentRight="true"
|
||||
|
||||
android:singleLine="true"
|
||||
android:ellipsize="marquee" />
|
||||
android:layout_width="fill_parent" android:layout_height="26dip"
|
||||
|
||||
android:layout_toRightOf="@id/history_cell_icon"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentRight="true" android:singleLine="true"
|
||||
android:ellipsize="marquee" />
|
||||
|
||||
<TextView android:id="@+id/history_cell_first_line"
|
||||
|
||||
android:layout_width="fill_parent" android:layout_height="wrap_content"
|
||||
|
||||
android:layout_toRightOf="@id/history_cell_icon"
|
||||
android:layout_alignParentRight="true" android:layout_alignParentTop="true"
|
||||
android:layout_above="@id/history_cell_second_line"
|
||||
android:layout_alignWithParentIfMissing="true" android:gravity="center_vertical" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/history_cell_first_line"
|
||||
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:layout_toRightOf="@id/history_cell_icon"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_above="@id/history_cell_second_line"
|
||||
android:layout_alignWithParentIfMissing="true"
|
||||
|
||||
android:gravity="center_vertical"/>
|
||||
</RelativeLayout>
|
|
@ -34,6 +34,7 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class HistoryActivity extends ListActivity {
|
||||
|
@ -46,6 +47,22 @@ public class HistoryActivity extends ListActivity {
|
|||
|
||||
|
||||
@Override
|
||||
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||
super.onListItemClick(l, v, position, id);
|
||||
TextView lFirstLineView = (TextView) v.findViewById(R.id.history_cell_first_line);
|
||||
TextView lSecondLineView = (TextView) v.findViewById(R.id.history_cell_second_line);
|
||||
if (lSecondLineView.getVisibility() == View.GONE) {
|
||||
// no display name
|
||||
DialerActivity.getDialer().setContactAddress(lFirstLineView.getText().toString(), null);
|
||||
} else {
|
||||
DialerActivity.getDialer().setContactAddress(lSecondLineView.getText().toString()
|
||||
,lFirstLineView.getText().toString());
|
||||
}
|
||||
LinphoneActivity.instance().getTabHost().setCurrentTabByTag(LinphoneActivity.DIALER_TAB);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
setListAdapter(new CallHistoryAdapter(this));
|
||||
|
@ -73,21 +90,29 @@ public class HistoryActivity extends ListActivity {
|
|||
}
|
||||
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
LinphoneCallLog lLog = mLogs.get(position);
|
||||
View lView=null;
|
||||
if (convertView !=null) {
|
||||
lView = convertView;
|
||||
} else {
|
||||
lView = mInflater.inflate(R.layout.history_cell, parent,false);
|
||||
|
||||
}
|
||||
LinphoneCallLog lLog = mLogs.get(mLogs.size()-position-1);
|
||||
LinphoneAddress lAddress;
|
||||
lView = mInflater.inflate(R.layout.history_cell, null);
|
||||
TextView lFirstLineView = (TextView) lView.findViewById(R.id.history_cell_first_line);
|
||||
TextView lSecondLineView = (TextView) lView.findViewById(R.id.history_cell_second_line);
|
||||
ImageView lDirectionImage = (ImageView) lView.findViewById(R.id.history_cell_icon);
|
||||
ImageView lDirectionImageIn = (ImageView) lView.findViewById(R.id.history_cell_icon_in);
|
||||
ImageView lDirectionImageOut = (ImageView) lView.findViewById(R.id.history_cell_icon_out);
|
||||
|
||||
if (lLog.getDirection() == CallDirection.Callincoming) {
|
||||
lAddress = lLog.getFrom();
|
||||
lDirectionImage.setImageResource(R.drawable.in_call);
|
||||
lDirectionImageIn.setVisibility(View.VISIBLE);
|
||||
lDirectionImageOut.setVisibility(View.GONE);
|
||||
|
||||
} else {
|
||||
lAddress = lLog.getTo();
|
||||
lDirectionImage.setImageResource(R.drawable.out_call);
|
||||
lDirectionImageIn.setVisibility(View.GONE);
|
||||
lDirectionImageOut.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (lAddress.getDisplayName() == null) {
|
||||
|
@ -96,6 +121,7 @@ public class HistoryActivity extends ListActivity {
|
|||
} else {
|
||||
lFirstLineView.setText(lAddress.getDisplayName());
|
||||
lSecondLineView.setText(lAddress.getUserName());
|
||||
lSecondLineView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
return lView;
|
||||
|
|
|
@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
*/
|
||||
|
||||
package org.linphone;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceActivity;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Linphone.java
|
||||
LinphoneService.java
|
||||
Copyright (C) 2010 Belledonne Communications, Grenoble, France
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
|
@ -32,6 +32,7 @@ import org.linphone.core.LinphoneCoreException;
|
|||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
import org.linphone.core.LinphoneProxyConfig;
|
||||
import org.linphone.core.LinphoneCore.GeneralState;
|
||||
|
||||
|
||||
import android.app.AlertDialog;
|
||||
|
@ -67,7 +68,7 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
|
|||
private SharedPreferences mPref;
|
||||
Timer mTimer = new Timer("Linphone scheduler");
|
||||
|
||||
private Handler mIteratehandler;
|
||||
private Handler mHandler = new Handler() ;
|
||||
|
||||
static LinphoneService instance() {
|
||||
if (theLinphone == null) {
|
||||
|
@ -92,17 +93,11 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
|
|||
, null);
|
||||
|
||||
initFromConf();
|
||||
mIteratehandler = new Handler() {
|
||||
public void handleMessage(Message msg) {
|
||||
//iterate is called inside an Android handler to allow UI interaction within LinphoneCoreListener
|
||||
mLinphoneCore.iterate();
|
||||
}
|
||||
};
|
||||
|
||||
TimerTask lTask = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
mIteratehandler.sendEmptyMessage(0);
|
||||
mLinphoneCore.iterate();
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -159,17 +154,35 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
|
|||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
public void displayStatus(LinphoneCore lc, String message) {
|
||||
public void displayStatus(final LinphoneCore lc, final String message) {
|
||||
Log.i(TAG, message);
|
||||
if (DialerActivity.getDialer()!=null) DialerActivity.getDialer().displayStatus(lc,message);
|
||||
if (DialerActivity.getDialer()!=null) {
|
||||
mHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
DialerActivity.getDialer().displayStatus(lc,message);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
public void displayWarning(LinphoneCore lc, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
public void generalState(LinphoneCore lc, LinphoneCore.GeneralState state) {
|
||||
public void generalState(final LinphoneCore lc, final LinphoneCore.GeneralState state) {
|
||||
Log.i(TAG, "new state ["+state+"]");
|
||||
if (DialerActivity.getDialer()!=null) DialerActivity.getDialer().generalState(lc,state);
|
||||
if (state == GeneralState.GSTATE_POWER_OFF) {
|
||||
//just exist
|
||||
System.exit(0);
|
||||
}
|
||||
if (DialerActivity.getDialer()!=null) {
|
||||
mHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
DialerActivity.getDialer().generalState(lc,state);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
public void inviteReceived(LinphoneCore lc, String from) {
|
||||
// TODO Auto-generated method stub
|
||||
|
@ -256,7 +269,8 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
|
|||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
System.exit(0); // FIXME to destroy liblinphone
|
||||
mTimer.cancel();
|
||||
mLinphoneCore.destroy();
|
||||
}
|
||||
|
||||
}
|
|
@ -123,4 +123,9 @@ public interface LinphoneCore {
|
|||
*/
|
||||
public List<LinphoneCallLog> getCallLogs();
|
||||
|
||||
/**
|
||||
* destroy linphone core and free all underlying resources
|
||||
*/
|
||||
public void destroy();
|
||||
|
||||
}
|
||||
|
|
|
@ -23,11 +23,15 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.linphone.LinphoneService;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
class LinphoneCoreImpl implements LinphoneCore {
|
||||
|
||||
private final LinphoneCoreListener mListener;
|
||||
private final long nativePtr;
|
||||
private long nativePtr = 0;
|
||||
private native long newLinphoneCore(LinphoneCoreListener listener,String userConfig,String factoryConfig,Object userdata);
|
||||
private native void iterate(long nativePtr);
|
||||
private native long getDefaultProxyConfig(long nativePtr);
|
||||
|
@ -46,22 +50,29 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
private native void acceptCall(long nativePtr);
|
||||
private native long getCallLog(long nativePtr,int position);
|
||||
private native int getNumberOfCallLogs(long nativePtr);
|
||||
private native void delete(long nativePtr);
|
||||
|
||||
|
||||
LinphoneCoreImpl(LinphoneCoreListener listener, File userConfig,File factoryConfig,Object userdata) throws IOException {
|
||||
mListener=listener;
|
||||
nativePtr = newLinphoneCore(listener,userConfig.getCanonicalPath(),factoryConfig.getCanonicalPath(),userdata);
|
||||
}
|
||||
protected void finalize() throws Throwable {
|
||||
|
||||
}
|
||||
|
||||
public synchronized void addAuthInfo(LinphoneAuthInfo info) {
|
||||
isValid();
|
||||
addAuthInfo(nativePtr,((LinphoneAuthInfoImpl)info).nativePtr);
|
||||
}
|
||||
|
||||
public synchronized LinphoneProxyConfig createProxyConfig(String identity, String proxy,String route,boolean enableRegister) throws LinphoneCoreException {
|
||||
isValid();
|
||||
return new LinphoneProxyConfigImpl(identity, proxy, route,enableRegister);
|
||||
}
|
||||
|
||||
public synchronized LinphoneProxyConfig getDefaultProxyConfig() {
|
||||
isValid();
|
||||
long lNativePtr = getDefaultProxyConfig(nativePtr);
|
||||
if (lNativePtr!=0) {
|
||||
return new LinphoneProxyConfigImpl(lNativePtr);
|
||||
|
@ -71,32 +82,40 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
}
|
||||
|
||||
public synchronized void invite(String uri) {
|
||||
isValid();
|
||||
invite(nativePtr,uri);
|
||||
}
|
||||
|
||||
public synchronized void iterate() {
|
||||
isValid();
|
||||
iterate(nativePtr);
|
||||
}
|
||||
|
||||
public synchronized void setDefaultProxyConfig(LinphoneProxyConfig proxyCfg) {
|
||||
isValid();
|
||||
setDefaultProxyConfig(nativePtr,((LinphoneProxyConfigImpl)proxyCfg).nativePtr);
|
||||
}
|
||||
public synchronized void addtProxyConfig(LinphoneProxyConfig proxyCfg) throws LinphoneCoreException{
|
||||
isValid();
|
||||
if (addProxyConfig(nativePtr,((LinphoneProxyConfigImpl)proxyCfg).nativePtr) !=0) {
|
||||
throw new LinphoneCoreException("bad proxy config");
|
||||
}
|
||||
}
|
||||
public synchronized void clearAuthInfos() {
|
||||
isValid();
|
||||
clearAuthInfos(nativePtr);
|
||||
|
||||
}
|
||||
public synchronized void clearProxyConfigs() {
|
||||
isValid();
|
||||
clearProxyConfigs(nativePtr);
|
||||
}
|
||||
public synchronized void terminateCall() {
|
||||
isValid();
|
||||
terminateCall(nativePtr);
|
||||
}
|
||||
public synchronized LinphoneAddress getRemoteAddress() {
|
||||
isValid();
|
||||
long ptr = getRemoteAddress(nativePtr);
|
||||
if (ptr==0) {
|
||||
return null;
|
||||
|
@ -105,20 +124,35 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
}
|
||||
}
|
||||
public synchronized boolean isIncall() {
|
||||
isValid();
|
||||
return isInCall(nativePtr);
|
||||
}
|
||||
public synchronized boolean isInComingInvitePending() {
|
||||
isValid();
|
||||
return isInComingInvitePending(nativePtr);
|
||||
}
|
||||
public synchronized void acceptCall() {
|
||||
isValid();
|
||||
acceptCall(nativePtr);
|
||||
|
||||
}
|
||||
public List<LinphoneCallLog> getCallLogs() {
|
||||
public synchronized List<LinphoneCallLog> getCallLogs() {
|
||||
isValid();
|
||||
List<LinphoneCallLog> logs = new ArrayList<LinphoneCallLog>();
|
||||
for (int i=0;i < getNumberOfCallLogs(nativePtr);i++) {
|
||||
logs.add(new LinphoneCallLogImpl(getCallLog(nativePtr, i)));
|
||||
}
|
||||
return logs;
|
||||
}
|
||||
public synchronized void destroy() {
|
||||
isValid();
|
||||
delete(nativePtr);
|
||||
nativePtr = 0;
|
||||
}
|
||||
|
||||
private void isValid() {
|
||||
if (nativePtr == 0) {
|
||||
throw new RuntimeException("object already destroyed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue