Add relativeLayout for left menu

This commit is contained in:
Margaux Clerc 2015-08-14 11:03:40 +02:00
parent 7fe3703447
commit 6870dec8b1
20 changed files with 584 additions and 221 deletions

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.linphone"
android:versionCode="2411" android:installLocation="auto">
android:versionCode="2500" android:installLocation="auto">
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="22"/>
<!-- Permissions for Push Notification -->

View file

@ -1,4 +1,4 @@
source.dir=src:submodules/linphone/mediastreamer2/java/src:submodules/linphone/java/j2se:submodules/linphone/java/common:submodules/linphone/java/impl:submodules/linphone/coreapi/help/java:submodules/externals/axmlrpc/src/main/java
key.store=bc-android.keystore
key.alias=nw8000
version.name=2.4.0
version.name=2.5.0

View file

@ -134,7 +134,7 @@
<property name="out.library.jar.file" location="${out.absolute.dir}/linphone.jar" />
<jar destfile="${out.library.jar.file}">
<fileset dir="${out.classes.absolute.dir}"
includes="org/linphone/mediastream/**/*.class org/linphone/core/**/*.class org/linphone/**/*.class"/>
includes="org/linphone/mediastream/**/*.class org/linphone/core/**/*.class org/linphone/**/*.class de/timroes/axmlrpc/**/*.class de/timroes/base64/Base64.class"/>
<fileset dir="submodules/linphone/java" >
<include name="common/org/linphone/core/*.java"/>
<include name="j2se/org/linphone/core/*.java"/>

View file

@ -50,10 +50,11 @@
<ProgressBar
android:id="@+id/spinner"
android:visibility="gone"
android:indeterminate="true"
android:visibility="gone"
android:layout_marginTop="20dp"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
android:layout_height="5dp" />
<TextView
android:id="@+id/time"

View file

@ -1,12 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textColor="@color/text_contrast"
android:background="?android:attr/activatedBackgroundIndicator"
android:minHeight="?android:attr/listPreferredItemHeightSmall"/>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@color/colorH">
<ImageView
android:id="@+id/icon"
android:layout_width="25dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:src="@drawable/options_default"
android:layout_centerVertical="true" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_toRightOf="@id/icon"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:paddingRight="40dp"/>
</RelativeLayout>

View file

@ -187,13 +187,103 @@
</RelativeLayout>
<!-- The navigation drawer -->
<ListView android:id="@+id/left_drawer"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="@color/background"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/left_drawer"
android:layout_gravity="start">
<RelativeLayout
android:id="@+id/headerLayout"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@color/colorF">
<ImageView
android:id="@+id/icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentTop="true"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:src="@drawable/avatar"
android:layout_centerVertical="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/icon">
<TextView
android:id="@+id/title"
android:text="CLERC Margaux"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/font7"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="bottom"/>
<TextView
android:id="@+id/subtitle"
android:gravity="top"
android:text="margaux-mac@sip.linphone.org"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/icon"
style="@style/font3"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:textAppearance="?android:attr/textAppearanceListItemSmall"/>
</LinearLayout>
</RelativeLayout>
<ListView android:id="@+id/list_drawer"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="@color/background"/>
<RelativeLayout
android:id="@+id/exitLayout"
android:gravity="bottom"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@color/colorA">
<ImageView
android:id="@+id/lol"
android:layout_width="25dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:src="@drawable/quit_default"
android:layout_centerVertical="true" />
<TextView
android:id="@+id/exit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/lol"
android:text="@string/menu_exit"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:paddingRight="40dp"/>
</RelativeLayout>
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>

View file

@ -401,6 +401,9 @@
<string name="error_incompatible_media">Incompatible media parameters</string>
<string name="error_low_bandwidth">Your correspondent has low bandwidth, video can\'t be started</string>
<string name="error_network_unreachable">Network is unreachable</string>
<string name="error_bad_credentials">Bad credentials</string>
<string name="error_unauthorized">Unauthorized</string>
<string name="error_io_error">Network error</string>
<string name="today">Today</string>
<string name="yesterday">Yesterday</string>
<string name="call_state_missed">Missed</string>

View file

@ -35,6 +35,7 @@ import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen;
import android.text.InputType;
import android.view.WindowManager;
/**
* @author Sylvain Berfini
@ -65,7 +66,9 @@ public class AccountPreferencesFragment extends PreferencesListFragment {
} else {
manageAccountPreferencesFields(screen);
}
// Force hide keyboard
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
public static boolean isEditTextEmpty(String s){
@ -496,7 +499,7 @@ public class AccountPreferencesFragment extends PreferencesListFragment {
} catch (LinphoneCoreException e) {
e.printStackTrace();
}
LinphoneActivity.instance().isNewProxyConfig();
LinphoneManager.getLc().refreshRegisters();
}
}

View file

@ -21,9 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import android.content.CursorLoader;
import android.graphics.Matrix;
import java.util.ArrayList;
import java.util.List;
@ -33,7 +31,6 @@ import org.linphone.compatibility.Compatibility;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneBuffer;
import org.linphone.core.LinphoneChatMessage;
import org.linphone.core.LinphoneChatMessage.LinphoneChatMessageListener;
import org.linphone.core.LinphoneChatRoom;
import org.linphone.core.LinphoneContent;
import org.linphone.core.LinphoneCore;
@ -45,6 +42,7 @@ import org.linphone.mediastream.Log;
import org.linphone.ui.BubbleChat;
import android.media.ExifInterface;
import android.support.v4.content.CursorLoader;
import android.annotation.SuppressLint;
import android.app.Activity;
@ -62,7 +60,7 @@ import android.os.Bundle;
import android.os.Environment;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.app.Fragment;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
@ -85,7 +83,7 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
public class ChatFragment extends Fragment implements OnClickListener, LinphoneChatMessageListener {
public class ChatFragment extends Fragment implements OnClickListener, LinphoneChatMessage.LinphoneChatMessageListener {
private static ChatFragment instance;
private static final int ADD_PHOTO = 1337;
@ -113,9 +111,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
private ChatMessageAdapter adapter;
private LinphoneCoreListenerBase mListener;
private ByteArrayOutputStream mDownloadedImageStream;
private ByteArrayInputStream mUploadingImageStream;
private int mDownloadedImageStreamSize;
private LinphoneChatMessage currentMessageInFileTransferUploadState;
public static boolean isInstanciated() {
@ -127,7 +123,8 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
super.onCreate(savedInstanceState);
instance = this;
View view = inflater.inflate(R.layout.chat, container, false);
LinphoneManager.addListener(this);
// Retain the fragment across configuration changes
setRetainInstance(true);
@ -210,6 +207,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
progressBar.setProgress(0);
currentMessageInFileTransferUploadState.cancelFileTransfer();
currentMessageInFileTransferUploadState = null;
LinphoneManager.getInstance().setUploadPendingFileMessage(null);
}
}
});
@ -227,6 +225,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
LinphoneAddress from = cr.getPeerAddress();
if (from.asStringUriOnly().equals(sipUri)) {
invalidate();
messagesList.setSelection(adapter.getCount()-1);
}
}
@ -256,7 +255,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
// Force hide keyboard
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
return view;
}
@ -299,7 +297,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
topBar.setVisibility(View.GONE);
}
//contactPicture.setVisibility(View.GONE);
//scrollToEnd();
}
public void hideKeyboardVisibleMode() {
@ -308,7 +305,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
if (isOrientationLandscape && topBar != null) {
topBar.setVisibility(View.VISIBLE);
}
//scrollToEnd();
}
class ChatMessageAdapter extends BaseAdapter {
@ -343,11 +339,23 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
public View getView(int position, View convertView, ViewGroup parent) {
LinphoneChatMessage message = history[position];
BubbleChat bubble = new BubbleChat(context, message, ChatFragment.this);
BubbleChat bubble = new BubbleChat(context, message);
View v = bubble.getView();
registerForContextMenu(v);
RelativeLayout rlayout = new RelativeLayout(context);
if(message.isOutgoing()){
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
layoutParams.setMargins(100, 10, 10, 10);
v.setLayoutParams(layoutParams);
} else {
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
layoutParams.setMargins(10, 10, 100, 10);
v.setLayoutParams(layoutParams);
}
rlayout.addView(v);
return rlayout;
@ -469,8 +477,14 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
lc.removeListener(mListener);
}
LinphoneManager.removeListener(this);
onSaveInstanceState(getArguments());
uploadLayout.setVisibility(View.GONE);
textLayout.setVisibility(View.VISIBLE);
progressBar.setProgress(0);
//Hide keybord
InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(message.getWindowToken(), 0);
@ -495,12 +509,34 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
LinphoneActivity.instance().updateChatFragment(this);
}
LinphoneManager.addListener(this);
final LinphoneChatMessage msg = LinphoneManager.getInstance().getMessageUploadPending();
if(msg != null && msg.getTo().asString().equals(sipUri)){
uploadLayout.setVisibility(View.VISIBLE);
textLayout.setVisibility(View.GONE);
if(msg.getFileTransferInformation() != null){
progressBar.setProgress(msg.getFileTransferInformation().getRealSize());
}
cancelUpload.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
uploadLayout.setVisibility(View.GONE);
textLayout.setVisibility(View.VISIBLE);
progressBar.setProgress(0);
msg.cancelFileTransfer();
LinphoneManager.getInstance().setUploadPendingFileMessage(null);
}
});
}
String draft = getArguments().getString("messageDraft");
message.setText(draft);
remoteComposing.setVisibility(chatRoom.isRemoteComposing() ? View.VISIBLE : View.GONE);
dispayMessageList();
super.onResume();
}
@ -549,13 +585,14 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
if (chatRoom != null && messageToSend != null && messageToSend.length() > 0 && isNetworkReachable) {
LinphoneChatMessage message = chatRoom.createLinphoneChatMessage(messageToSend);
message.setListener(this);
chatRoom.sendChatMessage(message);
if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance().onMessageSent(sipUri, messageToSend);
}
message.setListener(LinphoneManager.getInstance());
invalidate();
Log.i("Sent message current status: " + message.getStatus());
} else if (!isNetworkReachable && LinphoneActivity.isInstanciated()) {
@ -607,7 +644,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
}
// Rotate the bitmap if possible/needed, using EXIF data
Log.w(path);
try {
if (path != null) {
ExifInterface exif = new ExifInterface(path);
@ -645,9 +681,12 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
content.setName(fileName);
LinphoneChatMessage message = chatRoom.createFileTransferMessage(content);
message.setListener(ChatFragment.this);
message.setListener(LinphoneManager.getInstance());
message.setAppData(path);
LinphoneManager.getInstance().setUploadPendingFileMessage(message);
LinphoneManager.getInstance().setUploadingImageStream(mUploadingImageStream);
chatRoom.sendChatMessage(message);
currentMessageInFileTransferUploadState = message;
}
@ -748,32 +787,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
@Override
public void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, State state) {
if (LinphoneActivity.isInstanciated() && state != LinphoneChatMessage.State.InProgress) {
if (msg != null) {
LinphoneActivity.instance().onMessageStateChanged(sipUri, msg.getText(), state.toInt());
}
invalidate();
}
if (state == State.FileTransferDone) {
if (mDownloadedImageStream != null) {
byte[] bytes = mDownloadedImageStream.toByteArray();
Bitmap bm = BitmapFactory.decodeByteArray(bytes, 0, mDownloadedImageStreamSize);
String path = msg.getExternalBodyUrl();
String fileName = path.substring(path.lastIndexOf("/") + 1);
String url = MediaStore.Images.Media.insertImage(getActivity().getContentResolver(), bm, fileName, null);
if (url != null) {
msg.setAppData(url);
}
mDownloadedImageStream = null;
mDownloadedImageStreamSize = 0;
} else if (mUploadingImageStream != null) {
mUploadingImageStream = null;
}
}
if (state == State.FileTransferDone || state == State.FileTransferError) {
uploadLayout.setVisibility(View.GONE);
textLayout.setVisibility(View.VISIBLE);
@ -785,33 +798,10 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
@Override
public void onLinphoneChatMessageFileTransferReceived(LinphoneChatMessage msg, LinphoneContent content, LinphoneBuffer buffer) {
if (mDownloadedImageStream == null) {
mDownloadedImageStream = new ByteArrayOutputStream();
mDownloadedImageStreamSize = 0;
}
if (buffer != null && buffer.getSize() > 0) {
try {
mDownloadedImageStream.write(buffer.getContent());
mDownloadedImageStreamSize += buffer.getSize();
} catch (IOException e) {
Log.e(e);
}
}
}
@Override
public void onLinphoneChatMessageFileTransferSent(LinphoneChatMessage msg, LinphoneContent content, int offset, int size, LinphoneBuffer bufferToFill) {
if (mUploadingImageStream != null && size > 0) {
byte[] data = new byte[size];
int read = mUploadingImageStream.read(data, 0, size);
if (read > 0) {
bufferToFill.setContent(data);
bufferToFill.setSize(read);
} else {
Log.e("Error, upload task asking for more bytes(" + size + ") than available (" + mUploadingImageStream.available() + ")");
}
}
}
@Override

View file

@ -92,8 +92,11 @@ public class ContactsManager {
initializeContactManager(context,contentResolver);
Account newAccount = new Account(context.getString(R.string.sync_account_name), context.getString(R.string.sync_account_type));
AccountManager accountManager = (AccountManager) context.getSystemService(context.ACCOUNT_SERVICE);
accountManager.addAccountExplicitly(newAccount, null, null);
mAccount = newAccount;
if(accountManager.addAccountExplicitly(newAccount, null, null)){
mAccount = newAccount;
} else {
mAccount = null;
}
}
public String getDisplayName(String firstName, String lastName) {

View file

@ -43,6 +43,7 @@ import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreFactory;
import org.linphone.core.LinphoneCoreListenerBase;
import org.linphone.core.LinphoneProxyConfig;
import org.linphone.core.Reason;
import org.linphone.mediastream.Log;
import org.linphone.setup.RemoteProvisioningLoginActivity;
import org.linphone.setup.SetupActivity;
@ -50,19 +51,23 @@ import org.linphone.ui.AddressText;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.app.SearchManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.database.ContentObserver;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.v4.app.Fragment;
import android.support.v4.app.Fragment.SavedState;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.view.Gravity;
@ -85,6 +90,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.support.v4.widget.DrawerLayout;
@ -94,7 +100,7 @@ import android.support.v4.view.GravityCompat;
/**
* @author Sylvain Berfini
*/
public class LinphoneActivity extends Activity implements OnClickListener, ContactPicked {
public class LinphoneActivity extends FragmentActivity implements OnClickListener, ContactPicked {
public static final String PREF_FIRST_LAUNCH = "pref_first_launch";
private static final int SETTINGS_ACTIVITY = 123;
private static final int FIRST_LOGIN_ACTIVITY = 101;
@ -113,15 +119,17 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
private List<FragmentsAvailable> fragmentsHistory;
private Fragment dialerFragment, messageListFragment, friendStatusListenerFragment;
private ChatFragment chatFragment;
private Fragment.SavedState dialerSavedState;
private SavedState dialerSavedState;
private boolean newProxyConfig;
private boolean isAnimationDisabled = false, preferLinphoneContacts = false;
private OrientationEventListener mOrientationHelper;
private LinphoneCoreListenerBase mListener;
private String[] mParams;
private String mTitle;
private ListView mDrawerList;
private RelativeLayout mDrawerList;
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
ListView mDrawerListB;
static final boolean isInstanciated() {
return instance != null;
@ -190,7 +198,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
if (findViewById(R.id.fragmentContainer) != null) {
dialerFragment = new DialerFragment();
dialerFragment.setArguments(getIntent().getExtras());
getFragmentManager().beginTransaction().add(R.id.fragmentContainer, dialerFragment, currentFragment.toString()).commit();
getSupportFragmentManager().beginTransaction().add(R.id.fragmentContainer, dialerFragment, currentFragment.toString()).commit();
selectMenu(FragmentsAvailable.DIALER);
}
}
@ -216,6 +224,19 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
lc.removeAuthInfo(authInfo);
}
}
if(state.equals(RegistrationState.RegistrationFailed) && newProxyConfig) {
newProxyConfig = false;
if (proxy.getError() == Reason.BadCredentials) {
displayCustomToast(getString(R.string.error_bad_credentials), Toast.LENGTH_LONG);
}
if (proxy.getError() == Reason.Unauthorized) {
displayCustomToast(getString(R.string.error_unauthorized), Toast.LENGTH_LONG);
}
if (proxy.getError() == Reason.IOError) {
displayCustomToast(getString(R.string.error_io_error), Toast.LENGTH_LONG);
}
}
}
@Override
@ -230,11 +251,11 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
}
} else if (state == State.CallEnd || state == State.Error || state == State.CallReleased) {
// Convert LinphoneCore message for internalization
if (message != null && message.equals("Call declined.")) {
if (message != null && call.getReason() == Reason.Declined) {
displayCustomToast(getString(R.string.error_call_declined), Toast.LENGTH_LONG);
} else if (message != null && message.equals("Not Found")) {
} else if (message != null && call.getReason() == Reason.NotFound) {
displayCustomToast(getString(R.string.error_user_not_found), Toast.LENGTH_LONG);
} else if (message != null && message.equals("Unsupported media type")) {
} else if (message != null && call.getReason() == Reason.Media) {
displayCustomToast(getString(R.string.error_incompatible_media), Toast.LENGTH_LONG);
} else if (message != null && state == State.Error) {
displayCustomToast(getString(R.string.error_unknown) + " - " + message, Toast.LENGTH_LONG);
@ -278,54 +299,143 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
}
public void createDrawer() {
mTitle = "lala";
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mParams = getResources().getStringArray(R.array.menu_entry);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
mDrawerList = (RelativeLayout) findViewById(R.id.left_drawer);
mDrawerListB = (ListView) findViewById(R.id.list_drawer);
List<DrawerItem> dataList = new ArrayList<DrawerItem>();
dataList.add(new DrawerItem("About"));
dataList.add(new DrawerItem("Settings"));
dataList.add(new DrawerItem("Help"));
CustomDrawerAdapter adapter;
adapter = new CustomDrawerAdapter(this, R.layout.custom_drawer_item,
dataList);
mDrawerListB.setAdapter(adapter);
// set a custom shadow that overlays the main content when the drawer opens
//mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// set up the drawer's list view with items and click listener
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, mParams));
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
// enable ActionBar app icon to behave as action to toggle nav drawer
//getActionBar().setDisplayHomeAsUpEnabled(true);
//getActionBar().setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the sliding drawer and the action bar app icon
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.menu, /* nav drawer image to replace 'Up' caret */
R.string.menu_about, /* "open drawer" description for accessibility */
R.string.menu_exit /* "close drawer" description for accessibility */
) {
public void onDrawerClosed(View view) {
//getActionBar().setTitle(mTitle);
//invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
//getActionBar().setTitle(mTitle);
//invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
//mDrawerLayout.setDrawerListener(mDrawerToggle);
}
/* The click listner for ListView in the navigation drawer */
private class DrawerItemClickListener implements ListView.OnItemClickListener {
class DrawerItem {
String ItemName;
int imgResID;
String title;
boolean isAccount;
public DrawerItem(boolean isAccount) {
this(null, 0);
this.isAccount = isAccount;
}
public DrawerItem(String itemName, int imgResID) {
ItemName = itemName;
this.imgResID = imgResID;
}
public DrawerItem(String title) {
this(null, 0);
this.title = title;
}
public String getItemName() {
return ItemName;
}
public void setItemName(String itemName) {
ItemName = itemName;
}
public int getImgResID() {
return imgResID;
}
public void setImgResID(int imgResID) {
this.imgResID = imgResID;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public boolean isAccount() {
return isAccount;
}
}
public class CustomDrawerAdapter extends ArrayAdapter<DrawerItem> {
Context context;
List<DrawerItem> drawerItemList;
int layoutResID;
public CustomDrawerAdapter(Context context, int layoutResourceID,
List<DrawerItem> listItems) {
super(context, layoutResourceID, listItems);
this.context = context;
this.drawerItemList = listItems;
this.layoutResID = layoutResourceID;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
DrawerItemHolder drawerHolder;
View view = convertView;
if (view == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
drawerHolder = new DrawerItemHolder();
view = inflater.inflate(layoutResID, parent, false);
drawerHolder.ItemName = (TextView) view.findViewById(R.id.drawer_itemName);
drawerHolder.icon = (ImageView) view.findViewById(R.id.drawer_icon);
//drawerHolder. = (ImageView) view
// .findViewById(R.id.s);
// drawerHolder.title = (TextView) view.findViewById(R.id.drawerTitle);
}
return view;
}
private class DrawerItemHolder {
TextView ItemName, title;
ImageView icon;
LinearLayout itemLayout;
RelativeLayout headerLayout, exitLayout;
}
}
private void selectItem(int position) {
// update the main content by replacing fragments
/*Fragment fragment = new PlanetFragment();
@ -359,9 +469,9 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
break;
}
mDrawerList.setItemChecked(position, true);
mDrawerListB.setItemChecked(position, true);
//
mDrawerLayout.closeDrawer(mDrawerList);
mDrawerLayout.closeDrawer(mDrawerListB);
}
@Override
@ -379,14 +489,14 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
//mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggls
mDrawerToggle.onConfigurationChanged(newConfig);
//mDrawerToggle.onConfigurationChanged(newConfig);
}
@ -449,6 +559,10 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
//findViewById(R.id.fragmentContainer).setPadding(0, LinphoneUtils.pixelsToDpi(getResources(), 40), 0, 0);
}
public void isNewProxyConfig(){
newProxyConfig = true;
}
private void changeCurrentFragment(FragmentsAvailable newFragmentType, Bundle extras) {
changeCurrentFragment(newFragmentType, extras, false);
}
@ -461,7 +575,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
if (currentFragment == FragmentsAvailable.DIALER) {
try {
dialerSavedState = getFragmentManager().saveFragmentInstanceState(dialerFragment);
dialerSavedState = getSupportFragmentManager().saveFragmentInstanceState(dialerFragment);
} catch (Exception e) {
}
}
@ -546,7 +660,8 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
statusFragment.closeStatusBar();
}*/
FragmentTransaction transaction = getFragmentManager().beginTransaction();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
if (!withoutAnimation && !isAnimationDisabled && currentFragment.shouldAnimate()) {
if (newFragmentType.isRightOf(currentFragment)) {
@ -572,7 +687,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
}
transaction.replace(R.id.fragmentContainer, newFragment, newFragmentType.toString());
transaction.commitAllowingStateLoss();
getFragmentManager().executePendingTransactions();
getSupportFragmentManager().executePendingTransactions();
currentFragment = newFragmentType;
}
@ -591,7 +706,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
LinearLayout ll = (LinearLayout) findViewById(R.id.fragmentContainer2);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
if (newFragmentType.shouldAddItselfToTheRightOf(currentFragment)) {
ll.setVisibility(View.VISIBLE);
@ -620,7 +735,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
transaction.replace(R.id.fragmentContainer, newFragment);
}
transaction.commitAllowingStateLoss();
getFragmentManager().executePendingTransactions();
getSupportFragmentManager().executePendingTransactions();
currentFragment = newFragmentType;
if (newFragmentType == FragmentsAvailable.DIALER
@ -631,7 +746,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|| newFragmentType == FragmentsAvailable.CHATLIST
|| newFragmentType == FragmentsAvailable.HISTORY) {
try {
getFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
} catch (java.lang.IllegalStateException e) {
}
@ -666,7 +781,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
String callTime = secondsToDisplayableString(log.getCallDuration());
String callDate = String.valueOf(log.getTimestamp());
Fragment fragment2 = getFragmentManager().findFragmentById(R.id.fragmentContainer2);
Fragment fragment2 = getSupportFragmentManager().findFragmentById(R.id.fragmentContainer2);
if (fragment2 != null && fragment2.isVisible() && currentFragment == FragmentsAvailable.HISTORY_DETAIL) {
HistoryDetailFragment historyDetailFragment = (HistoryDetailFragment) fragment2;
historyDetailFragment.changeDisplayedHistory(sipUri, displayName, pictureUri, status, callTime, callDate);
@ -694,7 +809,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
}
public void displayContact(Contact contact, boolean chatOnly) {
Fragment fragment2 = getFragmentManager().findFragmentById(R.id.fragmentContainer2);
Fragment fragment2 = getSupportFragmentManager().findFragmentById(R.id.fragmentContainer2);
if (fragment2 != null && fragment2.isVisible() && currentFragment == FragmentsAvailable.CONTACT) {
ContactFragment contactFragment = (ContactFragment) fragment2;
contactFragment.changeDisplayedContact(contact);
@ -766,7 +881,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
if (isTablet()){
if (currentFragment == FragmentsAvailable.CHATLIST || currentFragment == FragmentsAvailable.CHAT){
Fragment fragment2 = getFragmentManager().findFragmentById(R.id.fragmentContainer2);
Fragment fragment2 = getSupportFragmentManager().findFragmentById(R.id.fragmentContainer2);
if (fragment2 != null && fragment2.isVisible() && currentFragment == FragmentsAvailable.CHAT) {
ChatFragment chatFragment = (ChatFragment) fragment2;
chatFragment.changeDisplayedChat(sipUri, displayName, pictureUri);

View file

@ -22,13 +22,17 @@ import static android.media.AudioManager.MODE_RINGTONE;
import static android.media.AudioManager.STREAM_RING;
import static android.media.AudioManager.STREAM_VOICE_CALL;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
@ -36,6 +40,7 @@ import java.util.TimerTask;
import org.linphone.compatibility.Compatibility;
import org.linphone.core.CallDirection;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneBuffer;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneCall.State;
import org.linphone.core.LinphoneCallParams;
@ -88,10 +93,12 @@ import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.Vibrator;
import android.provider.MediaStore;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.telephony.TelephonyManager;
@ -116,7 +123,7 @@ import android.widget.Toast;
* @author Guillaume Beraudo
*
*/
public class LinphoneManager implements LinphoneCoreListener {
public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessage.LinphoneChatMessageListener {
private static LinphoneManager instance;
private Context mServiceContext;
@ -133,9 +140,21 @@ public class LinphoneManager implements LinphoneCoreListener {
private ConnectivityManager mConnectivityManager;
private Handler mHandler = new Handler();
private WakeLock mIncallWakeLock;
private static List<LinphoneChatMessage> mPendingChatFileMessage;
private static LinphoneChatMessage mUploadPendingFileMessage;
public String wizardLoginViewDomain = null;
private static List<LinphoneChatMessage.LinphoneChatMessageListener> simpleListeners = new ArrayList<LinphoneChatMessage.LinphoneChatMessageListener>();
public static void addListener(LinphoneChatMessage.LinphoneChatMessageListener listener) {
if (!simpleListeners.contains(listener)) {
simpleListeners.add(listener);
}
}
public static void removeListener(LinphoneChatMessage.LinphoneChatMessageListener listener) {
simpleListeners.remove(listener);
}
protected LinphoneManager(final Context c) {
sExited = false;
mServiceContext = c;
@ -156,6 +175,7 @@ public class LinphoneManager implements LinphoneCoreListener {
mPowerManager = (PowerManager) c.getSystemService(Context.POWER_SERVICE);
mConnectivityManager = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
mR = c.getResources();
mPendingChatFileMessage = new ArrayList<LinphoneChatMessage>();
}
private static final int LINPHONE_VOLUME_STREAM = STREAM_VOICE_CALL;
@ -170,6 +190,7 @@ public class LinphoneManager implements LinphoneCoreListener {
private final String mPauseSoundFile;
private final String mChatDatabaseFile;
private final String mErrorToneFile;
private ByteArrayInputStream mUploadingImageStream;
private Timer mTimer;
@ -213,6 +234,98 @@ public class LinphoneManager implements LinphoneCoreListener {
return instance;
}
public void addDownloadMessagePending(LinphoneChatMessage message){
synchronized (mPendingChatFileMessage) {
mPendingChatFileMessage.add(message);
}
}
public boolean isMessagePending(LinphoneChatMessage message){
boolean messagePending = false;
synchronized (mPendingChatFileMessage) {
for (LinphoneChatMessage chat : mPendingChatFileMessage) {
if (chat.getStorageId() == message.getStorageId()) {
messagePending = true;
break;
}
}
}
return messagePending;
}
public void removePendingMessage(LinphoneChatMessage message){
synchronized (mPendingChatFileMessage) {
for (LinphoneChatMessage chat : mPendingChatFileMessage) {
if (chat.getStorageId() == message.getStorageId()) {
mPendingChatFileMessage.remove(chat);
}
break;
}
}
}
public void setUploadPendingFileMessage(LinphoneChatMessage message){
mUploadPendingFileMessage = message;
}
public LinphoneChatMessage getMessageUploadPending(){
return mUploadPendingFileMessage;
}
public void setUploadingImageStream(ByteArrayInputStream array){
this.mUploadingImageStream = array;
}
@Override
public void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, LinphoneChatMessage.State state) {
if (state == LinphoneChatMessage.State.FileTransferDone || state == LinphoneChatMessage.State.FileTransferError) {
if(msg.isOutgoing() && mUploadingImageStream != null){
mUploadPendingFileMessage = null;
mUploadingImageStream = null;
} else {
File file = new File(Environment.getExternalStorageDirectory(), msg.getFileTransferInformation().getName());
try {
String url = MediaStore.Images.Media.insertImage(getContext().getContentResolver(), file.getPath(), msg.getFileTransferInformation().getName(), null);
msg.setAppData(url);
file.delete();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
removePendingMessage(msg);
}
}
for (LinphoneChatMessage.LinphoneChatMessageListener l: simpleListeners) {
l.onLinphoneChatMessageStateChanged(msg, state);
}
}
@Override
public void onLinphoneChatMessageFileTransferReceived(LinphoneChatMessage msg, LinphoneContent content, LinphoneBuffer buffer) {
}
@Override
public void onLinphoneChatMessageFileTransferSent(LinphoneChatMessage msg, LinphoneContent content, int offset, int size, LinphoneBuffer bufferToFill) {
if (mUploadingImageStream != null && size > 0) {
byte[] data = new byte[size];
int read = mUploadingImageStream.read(data, 0, size);
if (read > 0) {
bufferToFill.setContent(data);
bufferToFill.setSize(read);
} else {
Log.e("Error, upload task asking for more bytes(" + size + ") than available (" + mUploadingImageStream.available() + ")");
}
}
}
@Override
public void onLinphoneChatMessageFileTransferProgressChanged(LinphoneChatMessage msg, LinphoneContent content, int offset, int total) {
for (LinphoneChatMessage.LinphoneChatMessageListener l: simpleListeners) {
l.onLinphoneChatMessageFileTransferProgressChanged(msg, content, offset, total);
}
}
private boolean isPresenceModelActivitySet() {
LinphoneCore lc = getLcIfManagerNotDestroyedOrNull();
if (isInstanciated() && lc != null) {
@ -331,7 +444,6 @@ public class LinphoneManager implements LinphoneCoreListener {
LinphoneManager.getLc().setVideoDevice(camId);
}
public static interface AddressType {
void setText(CharSequence s);
CharSequence getText();
@ -688,11 +800,6 @@ public class LinphoneManager implements LinphoneCoreListener {
public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {
}
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,
LinphoneAddress from, String message) {
//deprecated
}
@Override
public void dtmfReceived(LinphoneCore lc, LinphoneCall call, int dtmf) {
Log.d("DTMF received: " + dtmf);
@ -1097,7 +1204,6 @@ public class LinphoneManager implements LinphoneCoreListener {
return distanceInCm < threshold;
}
private static boolean sLastProximitySensorValueNearby;
private static Set<Activity> sProximityDependentActivities = new HashSet<Activity>();
private static SensorEventListener sProximitySensorListener = new SensorEventListener() {

View file

@ -430,8 +430,10 @@ public class LinphonePreferences {
prxCfg.setIdentity(identity);
prxCfg.done();
info.setUsername(username);
saveAuthInfo(info);
if(info != null) {
info.setUsername(username);
saveAuthInfo(info);
}
} catch (LinphoneCoreException e) {
e.printStackTrace();
}
@ -468,8 +470,10 @@ public class LinphonePreferences {
public void setAccountUserId(int n, String userId) {
LinphoneAuthInfo info = getClonedAuthInfo(n);
info.setUserId(userId);
saveAuthInfo(info);
if(info != null) {
info.setUserId(userId);
saveAuthInfo(info);
}
}
public String getAccountUserId(int n) {
@ -479,8 +483,10 @@ public class LinphonePreferences {
public void setAccountPassword(int n, String password) {
LinphoneAuthInfo info = getClonedAuthInfo(n);
info.setPassword(password);
saveAuthInfo(info);
if(info != null) {
info.setPassword(password);
saveAuthInfo(info);
}
}
public String getAccountPassword(int n) {
@ -492,8 +498,10 @@ public class LinphonePreferences {
try {
LinphoneAuthInfo authInfo = getClonedAuthInfo(n);
authInfo.setDomain(domain);
saveAuthInfo(authInfo);
if(authInfo != null) {
authInfo.setDomain(domain);
saveAuthInfo(authInfo);
}
LinphoneProxyConfig prxCfg = getProxyConfig(n);
prxCfg.edit();
@ -1026,7 +1034,7 @@ public class LinphonePreferences {
}
public boolean isAutoStartEnabled() {
return getConfig().getBool("app", "auto_start", false);
return getConfig().getBool("app", "auto_start", true);
}
public void setAutoStart(boolean autoStartEnabled) {

View file

@ -105,10 +105,14 @@ public class StatusFragment extends Fragment {
if (!isAttached || !LinphoneService.isReady()) {
return;
}
if (lc.getDefaultProxyConfig().equals(proxy)) {
statusLed.setImageResource(getStatusIconResource(state, true));
statusText.setText(getStatusIconText(state));
}
if (lc.getDefaultProxyConfig() != null && lc.getDefaultProxyConfig().equals(proxy)) {
statusLed.setImageResource(getStatusIconResource(state, true));
statusText.setText(getStatusIconText(state));
} else if(lc.getDefaultProxyConfig() == null) {
statusLed.setImageResource(getStatusIconResource(state, true));
statusText.setText(getStatusIconText(state));
}
try {
if (getResources().getBoolean(R.bool.lock_statusbar)) {
@ -516,6 +520,9 @@ public class StatusFragment extends Fragment {
CheckBox checkBox = (CheckBox) v;
if (checkBox.isChecked()) {
String tag = (String) checkBox.getTag();
if(tag.startsWith("sip:")) {
tag = tag.substring(4);
}
String sipAddress = tag.split(":")[0];
int accountPosition = Integer.parseInt(tag.split(":")[1]);

View file

@ -81,8 +81,6 @@ public class EchoCancellerCalibrationFragment extends Fragment {
return view;
}
public void enableEcCalibrationResultSending(boolean enabled) {
mSendEcCalibrationResult = enabled;
}
@ -111,9 +109,10 @@ public class EchoCancellerCalibrationFragment extends Fragment {
}
};
Log.i("Add echo canceller calibration result: manufacturer=" + Build.MANUFACTURER + " model=" + Build.MODEL + " status=" + status + " delay=" + delayMs + "ms");
client.callAsync(listener, "add_ec_calibration_result", Build.MANUFACTURER, Build.MODEL, status.toString(), delayMs);
}
Boolean hasBuiltInEchoCanceler = LinphoneManager.getLc().hasBuiltInEchoCanceler();
Log.i("Add echo canceller calibration result: manufacturer=" + Build.MANUFACTURER + " model=" + Build.MODEL + " status=" + status + " delay=" + delayMs + "ms" + " hasBuiltInEchoCanceler " + hasBuiltInEchoCanceler);
client.callAsync(listener, "add_ec_calibration_result", Build.MANUFACTURER, Build.MODEL, status.toString(), delayMs, hasBuiltInEchoCanceler);
}
catch(Exception ex) {}
}
}

View file

@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.LinphonePreferences;
import org.linphone.LinphonePreferences.AccountBuilder;
@ -194,7 +195,7 @@ public class SetupActivity extends Activity implements OnClickListener {
cancel.setEnabled(false);
} else {
if (mPrefs.isFirstLaunch()) {
mPrefs.setEchoCancellation(LinphoneManager.getLc().needsEchoCanceler());
mPrefs.setEchoCancellation(LinphoneManager.getLc().hasBuiltInEchoCanceler());
}
success();
}
@ -280,6 +281,9 @@ public class SetupActivity extends Activity implements OnClickListener {
username = username.substring(4);
}
if (username.contains("@"))
username = username.split("@")[0];
if(domain.startsWith("sip:")) {
domain = domain.substring(4);
}
@ -370,6 +374,7 @@ public class SetupActivity extends Activity implements OnClickListener {
public void success() {
mPrefs.firstLaunchSuccessful();
LinphoneActivity.instance().isNewProxyConfig();
setResult(Activity.RESULT_OK);
finish();
}

View file

@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.ref.WeakReference;
@ -25,8 +26,10 @@ import java.util.Calendar;
import java.util.HashMap;
import java.util.Map.Entry;
import org.linphone.LinphoneManager;
import org.linphone.LinphoneUtils;
import org.linphone.R;
import org.linphone.core.LinphoneBuffer;
import org.linphone.core.LinphoneChatMessage;
import org.linphone.core.LinphoneChatMessage.State;
import org.linphone.core.LinphoneContent;
@ -43,6 +46,7 @@ import android.graphics.drawable.Drawable;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.Html;
import android.text.Spannable;
@ -57,46 +61,33 @@ import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;
/**
* @author Sylvain Berfini
*/
@SuppressLint("SimpleDateFormat")
public class BubbleChat {
public class BubbleChat implements LinphoneChatMessage.LinphoneChatMessageListener {
private static final HashMap<String, Integer> emoticons = new HashMap<String, Integer>();
private RelativeLayout view;
private LinearLayout view;
private ImageView statusView;
private LinphoneChatMessage nativeMessage;
private LinphoneChatMessage.LinphoneChatMessageListener fileTransferListener;
private Context mContext;
private static final int SIZE_MAX = 512;
private ProgressBar spinner;
@SuppressLint("InflateParams")
public BubbleChat(final Context context, LinphoneChatMessage message, LinphoneChatMessage.LinphoneChatMessageListener listener) {
public BubbleChat(final Context context, LinphoneChatMessage message) {
if (message == null) {
return;
}
nativeMessage = message;
fileTransferListener = listener;
mContext = context;
view = new RelativeLayout(context);
LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
if (message.isOutgoing()) {
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
layoutParams.setMargins(10, 0, 10, 0);
view.setBackgroundResource(R.drawable.resizable_chat_bubble_outgoing);
}
else {
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
layoutParams.setMargins(10, 0, 10, 0);
view.setBackgroundResource(R.drawable.resizable_chat_bubble_incoming);
}
view.setId(message.getStorageId());
view.setLayoutParams(layoutParams);
@ -104,39 +95,55 @@ public class BubbleChat {
LinearLayout layout;
if (message.isOutgoing()) {
layout = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.chat_bubble_outgoing, null);
view = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.chat_bubble_outgoing, null);
view.setBackgroundResource(R.drawable.chat_bubble_outgoing);
} else {
layout = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.chat_bubble_incoming, null);
view = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.chat_bubble_incoming, null);
view.setBackgroundResource(R.drawable.chat_bubble_incoming);
}
view.setId(message.getStorageId());
spinner = (ProgressBar) view.findViewById(R.id.spinner);
String externalBodyUrl = message.getExternalBodyUrl();
LinphoneContent fileTransferContent = message.getFileTransferInformation();
if (externalBodyUrl != null || fileTransferContent != null) {
Button download = (Button) layout.findViewById(R.id.download);
ImageView imageView = (ImageView) layout.findViewById(R.id.image);
Button download = (Button) view.findViewById(R.id.download);
ImageView imageView = (ImageView) view.findViewById(R.id.image);
String appData = message.getAppData();
if (appData == null) {
download.setVisibility(View.VISIBLE);
download.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
v.setEnabled(false);
ProgressBar spinner = (ProgressBar) view.findViewById(R.id.spinner);
spinner.setVisibility(View.VISIBLE);
v.setVisibility(View.GONE);
LinphoneManager.addListener(this);
if(LinphoneManager.getInstance().isMessagePending(nativeMessage)){
download.setEnabled(false);
ProgressBar spinner = (ProgressBar) view.findViewById(R.id.spinner);
spinner.setVisibility(View.VISIBLE);
download.setVisibility(View.GONE);
} else {
download.setVisibility(View.VISIBLE);
download.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
v.setEnabled(false);
spinner.setVisibility(View.VISIBLE);
v.setVisibility(View.GONE);
nativeMessage.setListener(fileTransferListener);
nativeMessage.downloadFile();
}
});
File file = new File(Environment.getExternalStorageDirectory(), nativeMessage.getFileTransferInformation().getName());
nativeMessage.setListener(LinphoneManager.getInstance());
nativeMessage.setFileTransferFilepath(file.getPath());
nativeMessage.downloadFile();
LinphoneManager.getInstance().addDownloadMessagePending(nativeMessage);
}
});
}
} else {
imageView.setVisibility(View.VISIBLE);
loadBitmap(appData, imageView);
LinphoneManager.removeListener(this);
imageView.setVisibility(View.VISIBLE);
loadBitmap(appData, imageView);
}
} else {
TextView msgView = (TextView) layout.findViewById(R.id.message);
TextView msgView = (TextView) view.findViewById(R.id.message);
if (msgView != null) {
Spanned text = null;
String msg = message.getText();
@ -157,7 +164,7 @@ public class BubbleChat {
contact.setText(timestampToHumanDate(context, message.getTime()) + " - " + LinphoneUtils.getUsernameFromAddress(message.getFrom().asStringUriOnly()));
LinphoneChatMessage.State status = message.getStatus();
statusView = (ImageView) layout.findViewById(R.id.status);
statusView = (ImageView) view.findViewById(R.id.status);
if (statusView != null) {
if (status == LinphoneChatMessage.State.Delivered) {
statusView.setImageResource(R.drawable.chat_message_delivered);
@ -168,7 +175,7 @@ public class BubbleChat {
}
}
view.addView(layout);
//view.addView(layout);
}
public void updateStatusView() {
@ -290,7 +297,7 @@ public class BubbleChat {
task.execute(path);
}
}
private class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
public String path;
@ -397,4 +404,22 @@ public class BubbleChat {
}
return null;
}
@Override
public void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, State state) {
}
@Override
public void onLinphoneChatMessageFileTransferReceived(LinphoneChatMessage msg, LinphoneContent content, LinphoneBuffer buffer) {
}
@Override
public void onLinphoneChatMessageFileTransferSent(LinphoneChatMessage msg, LinphoneContent content, int offset, int size, LinphoneBuffer bufferToFill) {
}
@Override
public void onLinphoneChatMessageFileTransferProgressChanged(LinphoneChatMessage msg, LinphoneContent content, int offset, int total) {
if(nativeMessage.getStorageId() == msg.getStorageId())
spinner.setProgress(offset * 100 / total);
}
}

@ -1 +1 @@
Subproject commit 580012c556ba0e4d0f09bf3f182cdf55e030f215
Subproject commit 91ae7c164d9d20fd36657943a0aba807b4dfeb4f

@ -1 +1 @@
Subproject commit 157c61d2f5e6b476e8150cfff64e2142795e6d8a
Subproject commit 075f13f233c21caec79ca0e3ed3796f0e0082e4f

View file

@ -338,13 +338,6 @@ public class LinphoneTestManager implements LinphoneCoreListener{
}
@Override
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,
LinphoneAddress from, String message) {
// TODO Auto-generated method stub
}
@Override
public void messageReceived(LinphoneCore lc, LinphoneChatRoom cr,
LinphoneChatMessage message) {