Added About fragments that can replace either settings or chat

This commit is contained in:
Sylvain Berfini 2012-08-28 15:41:32 +02:00
parent a7ed31eac2
commit ff2aeded3c
19 changed files with 391 additions and 18 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/about_chat_over" />
<item android:state_selected="true"
android:drawable="@drawable/about_chat_selected" />
<item
android:drawable="@drawable/about_chat_default" />
</selector>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/chat_over" />
<item android:state_selected="true"
android:drawable="@drawable/chat_selected" />
<item
android:drawable="@drawable/chat_default" />
</selector>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/about_settings_over" />
<item android:state_selected="true"
android:drawable="@drawable/about_settings_selected" />
<item
android:drawable="@drawable/about_settings_default" />
</selector>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/settings_over" />
<item android:state_selected="true"
android:drawable="@drawable/settings_selected" />
<item
android:drawable="@drawable/settings_default" />
</selector>

32
res/layout/about.xml Normal file
View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/background"
android:gravity="center">
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/linphone_banner"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/about_text"
android:autoLink="web"
android:gravity="center"
android:paddingTop="50sp"
android:textStyle="bold"
android:textColor="@android:color/black"
android:id="@+id/AboutText"/>
<Button android:id="@+id/about_report_issue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/about_report_issue"
android:visibility="gone"
android:layout_marginTop="30sp"/>
</LinearLayout>

View file

@ -145,7 +145,30 @@
android:scaleType="fitXY" android:scaleType="fitXY"
android:src="@drawable/settings" /> android:src="@drawable/settings" />
<ImageView
android:id="@+id/about_settings"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.2"
android:adjustViewBounds="true"
android:contentDescription="@string/content_description_about"
android:scaleType="fitXY"
android:src="@drawable/about_settings" />
<ImageView
android:id="@+id/about_chat"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.2"
android:adjustViewBounds="true"
android:contentDescription="@string/content_description_about"
android:scaleType="fitXY"
android:src="@drawable/about_chat" />
<RelativeLayout <RelativeLayout
android:id="@+id/completeChat"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0.2"> android:layout_weight="0.2">

View file

@ -129,7 +129,30 @@
android:scaleType="fitXY" android:scaleType="fitXY"
android:src="@drawable/settings" /> android:src="@drawable/settings" />
<ImageView
android:id="@+id/about_settings"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.2"
android:adjustViewBounds="true"
android:contentDescription="@string/content_description_about"
android:scaleType="fitXY"
android:src="@drawable/about_settings" />
<ImageView
android:id="@+id/about_chat"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.2"
android:adjustViewBounds="true"
android:contentDescription="@string/content_description_about"
android:scaleType="fitXY"
android:src="@drawable/about_chat" />
<RelativeLayout <RelativeLayout
android:id="@+id/completeChat"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0.2"> android:layout_weight="0.2">

View file

@ -6,22 +6,28 @@
<string name="wizard_url">https://www.linphone.org/wizard.php</string> <string name="wizard_url">https://www.linphone.org/wizard.php</string>
<!-- Interface settings --> <!-- Interface settings -->
<bool name="use_simple_history">false</bool> <bool name="use_simple_history">true</bool>
<bool name="replace_settings_by_about">false</bool>
<bool name="replace_chat_by_about">false</bool>
<bool name="hide_camera_settings">false</bool> <bool name="hide_camera_settings">false</bool>
<bool name="hide_wizard">false</bool> <bool name="hide_wizard">false</bool>
<bool name="hide_accounts">false</bool> <bool name="hide_accounts">false</bool>
<bool name="useFirstLoginActivity">false</bool> <bool name="useFirstLoginActivity">false</bool>
<bool name="disable_animations">false</bool> <bool name="disable_animations">false</bool>
<bool name="lock_statusbar">false</bool> <bool name="lock_statusbar">false</bool>
<bool name="emoticons_in_messages">true</bool> <bool name="emoticons_in_messages">true</bool>
<bool name="only_display_username_if_unknown">true</bool> <bool name="only_display_username_if_unknown">true</bool>
<bool name="display_messages_time">true</bool> <!-- Used to show the time of each message arrival --> <bool name="display_messages_time">true</bool> <!-- Used to show the time of each message arrival -->
<bool name="display_time_aside">false</bool> <!-- if display_messages_time = true, display time on the side of the message instead of below --> <bool name="display_time_aside">false</bool> <!-- if display_messages_time = true, display time on the side of the message instead of below -->
<bool name="call_last_log_if_adress_is_empty">true</bool> <bool name="call_last_log_if_adress_is_empty">true</bool>
<bool name="allow_ringing_while_early_media">true</bool> <bool name="allow_ringing_while_early_media">true</bool>
<bool name="allow_transfers">true</bool> <bool name="allow_transfers">true</bool>
<bool name="allow_edit_in_dialer">true</bool> <bool name="allow_edit_in_dialer">true</bool>
<bool name="forbid_self_call">false</bool> <bool name="forbid_self_call">false</bool>
<string name="about_bugreport_email">linphone-android@belledonne-communications.com</string> <string name="about_bugreport_email">linphone-android@belledonne-communications.com</string>
</resources> </resources>

View file

@ -266,6 +266,7 @@
<!-- Used by Android to help blind people by describing them images --> <!-- Used by Android to help blind people by describing them images -->
<string name="content_description_add_contact">Add to contacts button</string> <string name="content_description_add_contact">Add to contacts button</string>
<string name="content_description_about"></string>
<string name="content_description_chat"></string> <string name="content_description_chat"></string>
<string name="content_description_dial_back"></string> <string name="content_description_dial_back"></string>
<string name="content_description_contact_picture"></string> <string name="content_description_contact_picture"></string>

View file

@ -0,0 +1,190 @@
package org.linphone;
/*
AboutFragment.java
Copyright (C) 2012 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import org.linphone.core.Log;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
/**
* @author Sylvain Berfini
*/
public class AboutFragment extends Fragment implements OnClickListener {
private Handler mHandler = new Handler();
private FragmentsAvailable about = FragmentsAvailable.ABOUT_INSTEAD_OF_CHAT;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (getArguments() != null && getArguments().getSerializable("About") != null) {
about = (FragmentsAvailable) getArguments().getSerializable("About");
}
View view = inflater.inflate(R.layout.about, container, false);
TextView aboutText = (TextView) view.findViewById(R.id.AboutText);
try {
aboutText.setText(String.format(getString(R.string.about_text), getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0).versionName));
} catch (NameNotFoundException e) {
Log.e(e, "cannot get version name");
}
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getActivity());
if (pref.getBoolean(getString(R.string.pref_debug_key), false)) {
View issue = view.findViewById(R.id.about_report_issue);
issue.setOnClickListener(this);
issue.setVisibility(View.VISIBLE);
}
return view;
}
@Override
public void onResume() {
super.onResume();
if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance().selectMenu(about);
}
}
private Thread thread;
@Override
public void onClick(View v) {
if (thread != null) return;
Toast.makeText(getActivity(), getString(R.string.about_reading_logs), Toast.LENGTH_LONG).show();
thread = new ReadLogThread();
thread.start();
}
private File writeLogs(String logs, File directory) {
File tempFile = null;
try {
tempFile = File.createTempFile("bugreport", ".txt", directory);
tempFile.deleteOnExit();
FileWriter writer = new FileWriter(tempFile);
writer.append(logs);
writer.close();
return tempFile;
} catch (IOException e) {
Toast.makeText(getActivity(), getString(R.string.about_error_generating_bugreport_attachement), Toast.LENGTH_LONG).show();
Log.e(e, "couldn't write to temporary file");
return null;
}
}
private void onLogsRead(String logs) {
if (logs == null) {
Toast.makeText(getActivity(), getString(R.string.about_logs_not_found), Toast.LENGTH_SHORT).show();
} else {
File tempFile = writeLogs(logs, null);
if (tempFile == null) {
// If writing to temporary file to default location failed
// Write one to our storage place
tempFile = writeLogs(logs, getActivity().getFilesDir());
}
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setType("plain/text");
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{getString(R.string.about_bugreport_email)});
intent.putExtra(Intent.EXTRA_SUBJECT,"Bug report " + getString(R.string.app_name) + "-android");
intent.putExtra(Intent.EXTRA_TEXT, getString(R.string.about_bugreport_email_text));
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tempFile));
intent = Intent.createChooser(intent,getString(R.string.about_mailer_chooser_text));
startActivityForResult(intent, 0);
}
}
private class ReadLogThread extends Thread {
@Override
public void run() {
final String logs = readLogs();
mHandler.post(new Runnable() {
@Override
public void run() {
onLogsRead(logs);
thread=null;
}
});
super.run();
}
}
private String readLogs() {
StringBuilder sb1 = null;
StringBuilder sb2 = null;
BufferedReader br = null;
Process p = null;
try {
p = Runtime.getRuntime().exec(new String[] {"logcat", "-d"});
br = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024);
String line;
while ((line = br.readLine()) != null) {
if (line.contains(LinphoneService.START_LINPHONE_LOGS)) {
if (sb1 != null) {
sb2 = sb1;
}
sb1 = new StringBuilder();
}
if (sb1 != null) {
sb1.append(line).append('\n');
}
}
if (sb1 == null) return null;
if (sb2 != null) {
sb1.append(sb2);
}
return sb1.toString();
} catch (IOException e) {
Log.e(e, "Error while reading logs");
return null;
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {}
}
if (p != null) {
p.destroy();
}
}
}
}

View file

@ -27,6 +27,8 @@ public enum FragmentsAvailable {
HISTORY_DETAIL, HISTORY_DETAIL,
CONTACTS, CONTACTS,
CONTACT, CONTACT,
ABOUT_INSTEAD_OF_SETTINGS,
ABOUT_INSTEAD_OF_CHAT,
SETTINGS, SETTINGS,
CHATLIST, CHATLIST,
CHAT; CHAT;
@ -56,11 +58,13 @@ public enum FragmentsAvailable {
case DIALER: case DIALER:
return CONTACTS.isRightOf(fragment) || fragment == CONTACT || fragment == CONTACTS; return CONTACTS.isRightOf(fragment) || fragment == CONTACT || fragment == CONTACTS;
case ABOUT_INSTEAD_OF_SETTINGS:
case SETTINGS: case SETTINGS:
return DIALER.isRightOf(fragment) || fragment == DIALER; return DIALER.isRightOf(fragment) || fragment == DIALER;
case ABOUT_INSTEAD_OF_CHAT:
case CHATLIST: case CHATLIST:
return SETTINGS.isRightOf(fragment) || fragment == SETTINGS; return SETTINGS.isRightOf(fragment) || fragment == SETTINGS || fragment == FragmentsAvailable.ABOUT_INSTEAD_OF_SETTINGS;
case CHAT: case CHAT:
return CHATLIST.isRightOf(fragment) || fragment == CHATLIST; return CHATLIST.isRightOf(fragment) || fragment == CHATLIST;

View file

@ -85,7 +85,7 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
private StatusFragment statusFragment; private StatusFragment statusFragment;
private TextView missedCalls, missedChats; private TextView missedCalls, missedChats;
private ImageView history, contacts, dialer, settings, chat; private ImageView history, contacts, dialer, settings, chat, aboutChat, aboutSettings;
private FragmentsAvailable currentFragment; private FragmentsAvailable currentFragment;
private Fragment dialerFragment, messageListenerFragment; private Fragment dialerFragment, messageListenerFragment;
private SavedState dialerSavedState; private SavedState dialerSavedState;
@ -134,6 +134,7 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
dialerFragment.setArguments(getIntent().getExtras()); dialerFragment.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction() getSupportFragmentManager().beginTransaction()
.add(R.id.fragmentContainer, dialerFragment).commit(); .add(R.id.fragmentContainer, dialerFragment).commit();
selectMenu(FragmentsAvailable.DIALER);
} }
} }
@ -158,11 +159,27 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
contacts.setOnClickListener(this); contacts.setOnClickListener(this);
dialer = (ImageView) findViewById(R.id.dialer); dialer = (ImageView) findViewById(R.id.dialer);
dialer.setOnClickListener(this); dialer.setOnClickListener(this);
dialer.setSelected(true);
settings = (ImageView) findViewById(R.id.settings); settings = (ImageView) findViewById(R.id.settings);
settings.setOnClickListener(this); settings.setOnClickListener(this);
chat = (ImageView) findViewById(R.id.chat); chat = (ImageView) findViewById(R.id.chat);
chat.setOnClickListener(this); chat.setOnClickListener(this);
aboutChat = (ImageView) findViewById(R.id.about_chat);
aboutSettings = (ImageView) findViewById(R.id.about_settings);
if (getResources().getBoolean(R.bool.replace_chat_by_about)) {
chat.setVisibility(View.GONE);
chat.setOnClickListener(null);
findViewById(R.id.completeChat).setVisibility(View.GONE);
aboutChat.setVisibility(View.VISIBLE);
aboutChat.setOnClickListener(this);
}
if (getResources().getBoolean(R.bool.replace_settings_by_about)) {
settings.setVisibility(View.GONE);
settings.setOnClickListener(null);
aboutSettings.setVisibility(View.VISIBLE);
aboutSettings.setOnClickListener(this);
}
missedCalls = (TextView) findViewById(R.id.missedCalls); missedCalls = (TextView) findViewById(R.id.missedCalls);
missedChats = (TextView) findViewById(R.id.missedChats); missedChats = (TextView) findViewById(R.id.missedChats);
} }
@ -209,6 +226,10 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
break; break;
case SETTINGS: case SETTINGS:
break; break;
case ABOUT_INSTEAD_OF_CHAT:
case ABOUT_INSTEAD_OF_SETTINGS:
newFragment = new AboutFragment();
break;
case CHAT: case CHAT:
newFragment = new ChatFragment(); newFragment = new ChatFragment();
messageListenerFragment = newFragment; messageListenerFragment = newFragment;
@ -418,19 +439,26 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
dialer.setSelected(true); dialer.setSelected(true);
} }
else if (id == R.id.settings) { else if (id == R.id.settings) {
// if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { Intent intent = new Intent(ACTION_MAIN);
// changeCurrentFragment(FragmentsAvailable.SETTINGS, null); intent.setClass(this, PreferencesActivity.class);
// settings.setSelected(true); startActivityForResult(intent, SETTINGS_ACTIVITY);
// } else { if (FragmentsAvailable.SETTINGS.isRightOf(currentFragment)) {
Intent intent = new Intent(ACTION_MAIN); Compatibility.overridePendingTransition(this, R.anim.slide_in_right_to_left, R.anim.slide_out_right_to_left);
intent.setClass(this, PreferencesActivity.class); } else {
startActivityForResult(intent, SETTINGS_ACTIVITY); Compatibility.overridePendingTransition(this, R.anim.slide_in_left_to_right, R.anim.slide_out_left_to_right);
if (FragmentsAvailable.SETTINGS.isRightOf(currentFragment)) { }
Compatibility.overridePendingTransition(this, R.anim.slide_in_right_to_left, R.anim.slide_out_right_to_left); }
} else { else if (id == R.id.about_chat) {
Compatibility.overridePendingTransition(this, R.anim.slide_in_left_to_right, R.anim.slide_out_left_to_right); Bundle b = new Bundle();
} b.putSerializable("About", FragmentsAvailable.ABOUT_INSTEAD_OF_CHAT);
// } changeCurrentFragment(FragmentsAvailable.ABOUT_INSTEAD_OF_CHAT, b);
aboutChat.setSelected(true);
}
else if (id == R.id.about_settings) {
Bundle b = new Bundle();
b.putSerializable("About", FragmentsAvailable.ABOUT_INSTEAD_OF_SETTINGS);
changeCurrentFragment(FragmentsAvailable.ABOUT_INSTEAD_OF_SETTINGS, b);
aboutSettings.setSelected(true);
} }
else if (id == R.id.chat) { else if (id == R.id.chat) {
changeCurrentFragment(FragmentsAvailable.CHATLIST, null); changeCurrentFragment(FragmentsAvailable.CHATLIST, null);
@ -444,6 +472,8 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
dialer.setSelected(false); dialer.setSelected(false);
settings.setSelected(false); settings.setSelected(false);
chat.setSelected(false); chat.setSelected(false);
aboutChat.setSelected(false);
aboutSettings.setSelected(false);
} }
@SuppressWarnings("incomplete-switch") @SuppressWarnings("incomplete-switch")
@ -466,6 +496,12 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene
case SETTINGS: case SETTINGS:
settings.setSelected(true); settings.setSelected(true);
break; break;
case ABOUT_INSTEAD_OF_CHAT:
aboutChat.setSelected(true);
break;
case ABOUT_INSTEAD_OF_SETTINGS:
aboutSettings.setSelected(true);
break;
case CHAT: case CHAT:
case CHATLIST: case CHATLIST:
chat.setSelected(true); chat.setSelected(true);

View file

@ -32,7 +32,7 @@ import android.widget.TextView;
* @author Sylvain Berfini * @author Sylvain Berfini
*/ */
public class LinphonePreferencesActivity extends PreferenceActivity implements OnClickListener { public class LinphonePreferencesActivity extends PreferenceActivity implements OnClickListener {
private ImageView history, contacts, dialer, settings, chat; private ImageView history, contacts, dialer, settings, chat, aboutChat, aboutSettings;
private TextView missedCalls; private TextView missedCalls;
@Override @Override
@ -61,12 +61,28 @@ public class LinphonePreferencesActivity extends PreferenceActivity implements O
chat = (ImageView) findViewById(R.id.chat); chat = (ImageView) findViewById(R.id.chat);
chat.setOnClickListener(this); chat.setOnClickListener(this);
missedCalls = (TextView) findViewById(R.id.missedCalls); missedCalls = (TextView) findViewById(R.id.missedCalls);
aboutChat = (ImageView) findViewById(R.id.about_chat);
aboutChat.setOnClickListener(this);
aboutSettings = (ImageView) findViewById(R.id.about_settings);
aboutSettings.setOnClickListener(this);
if (getResources().getBoolean(R.bool.replace_chat_by_about)) {
chat.setVisibility(View.GONE);
findViewById(R.id.completeChat).setVisibility(View.GONE);
aboutChat.setVisibility(View.VISIBLE);
}
if (getResources().getBoolean(R.bool.replace_settings_by_about)) {
settings.setVisibility(View.GONE);
aboutSettings.setVisibility(View.VISIBLE);
}
history.setSelected(false); history.setSelected(false);
contacts.setSelected(false); contacts.setSelected(false);
dialer.setSelected(false); dialer.setSelected(false);
settings.setSelected(true); settings.setSelected(true);
chat.setSelected(false); chat.setSelected(false);
aboutChat.setSelected(false);
aboutSettings.setSelected(false);
} }
@Override @Override
@ -86,6 +102,12 @@ public class LinphonePreferencesActivity extends PreferenceActivity implements O
else if (id == R.id.chat) { else if (id == R.id.chat) {
newFragment = FragmentsAvailable.CHATLIST; newFragment = FragmentsAvailable.CHATLIST;
} }
else if (id == R.id.about_chat) {
newFragment = FragmentsAvailable.ABOUT_INSTEAD_OF_CHAT;
}
else if (id == R.id.about_settings) {
newFragment = FragmentsAvailable.ABOUT_INSTEAD_OF_SETTINGS;
}
if (newFragment != FragmentsAvailable.SETTINGS) { if (newFragment != FragmentsAvailable.SETTINGS) {
Intent intent = new Intent(); Intent intent = new Intent();