一. 使用LocalBroadcastManager的registerReceiver相比Context的具有许多的好处 。
二 . 开机判断蓝牙设备连接状态以及连接类型:
BluetoothManager btMng = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter btAdapter = btMng.getAdapter();
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
int state = btAdapter.getProfileConnectionState(BluetoothProfile.A2DP);
switch(state) {
case BluetoothProfile.STATE_CONNECTED:
bluetoothAdapter.getProfileProxy(this, new BluetoothProfile.ServiceListener() {
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
List<BluetoothDevice> lists = proxy.getConnectedDevices();
if(lists!=null&&lists.size()>0) {
BluetoothDevice bt = lists.get(0);
}
}
@Override
public void onServiceDisconnected(int profile) {
}
},BluetoothProfile.A2DP);
break;
default:
break;
}
三 . 当使用AppCompatActivity时,可以随时更改Action Bar的名称:
getSupportActionBar().setTitle(R.string.scantitle);
四. ContextWrapper中有一个方法getPackageManager()可以的奥PackageManager的实例,
然后调用 hasSystemFeature()方法可以得到当前设备是否支持某一项功能:
if (!getPackageManager().hasSystemFeature(PackageManager.
FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_support, Toast.LENGTH_SHORT).show();
finish();
}
四. BaseAdapter,在需要列表 功能时,一定要学会使用此类。创建一个内部类继承自此类,在内部类中定义一个容器来存放你需要的数据类型:
private class LeDeviceListAdapter extends BaseAdapter {
private ArrayList<BluetoothDevice> mLeDevices;
private LayoutInflater mInflator;
public LeDeviceListAdapter() {
super();
mLeDevices = new ArrayList<BluetoothDevice>();
mInflator = DeviceScanActivity.this.getLayoutInflater();
}
public void addDevice(BluetoothDevice device) {
if (!mLeDevices.contains(device)) {
mLeDevices.add(device);
}
}
public BluetoothDevice getDevice(int position) {
return mLeDevices.get(position);
}
public void clear() {
mLeDevices.clear();
}
@Override
public int getCount() {
return mLeDevices.size();
}
@Override
public Object getItem(int i) {
return mLeDevices.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
// General ListView optimization code.
if (view == null) {
view = mInflator.inflate(R.layout.listitem_device, null);
viewHolder = new ViewHolder();
viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
viewHolder.deviceConnected = (ImageView) view.findViewById(R.id.scanicon);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
BluetoothDevice device = mLeDevices.get(i);
final String deviceName = device.getName();
if (deviceName != null && deviceName.length() > 0)
viewHolder.deviceName.setText(deviceName);
else
viewHolder.deviceName.setText(R.string.unknown_device);
viewHolder.deviceAddress.setText(device.getAddress());
if(mConnectedAddr != null && device.getAddress().equals(mConnectedAddr)){
viewHolder.deviceConnected.setImageResource(R.mipmap.ic_cab_done_holo_light);
}
return view;
}
}
五. LayoutInflater ,官方的介绍是:Instantiates a layout XML file into its corresponding {@link android.view.View}objects(用来加载布局的)。两种方式得到当前Context下的该类实例。
使用Activity的getLayoutInflater()方法。
使用Context的getSystemService方法。
使用LayoutInflater的静态方法from(Context context)。
LayoutInflater inflater = (LayoutInflater)context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE)
说到这里讲一下 ,layout_width和layout_height这两个参数,它们只有在布局文件中才具有作用,而setContentView会将当前layout添加到content中的FrameLayout中,id为content。
另外,当activity继承自AppCompatActivity时,可以使用getMenuLayoutInflater()方法获得menu的LayoutInflater。
六 Table页的实现。
首先在你的Activity中的布局文件里定义一个FragmentTabHost,如 :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout
android:id="@+id/tab_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight = "1"
android:layout_marginBottom="80dp"></FrameLayout>
<android.support.v4.app.FragmentTabHost
android:id="@+id/tab_host"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@android:color/darker_gray">
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight = "0">
</FrameLayout>
</android.support.v4.app.FragmentTabHost>
</RelativeLayout>
然后在你的Activity中,初始化该FragmentTabHost,如:
private FragmentTabHost mFragmentTabHost;
private String[] mIndicators = {"player","rate","settings"};
private Class[] mFragments = {PlayerFragment.class, HeartRateFragment.class, RateSettingsFragment.class};
private int[] mIndicatorsIron = {R.mipmap.hardware_headset,R.mipmap.rating_favorite,android.R.drawable.ic_menu_set_as};
private void init() {
mFragmentTabHost = (FragmentTabHost)findViewById(R.id.tab_host);
mFragmentTabHost.setup(this,getSupportFragmentManager(),R.id.tab_content);
mFragmentTabHost.setOnTabChangedListener(this);
for(int i = 0;i<mIndicators.length;i++) {
TabHost.TabSpec spec = mFragmentTabHost.newTabSpec(mIndicators[i]).setIndicator
(getIndicatorView(i));
if(i==1) {
Bundle bundle = new Bundle();
bundle.putString(EXTRAS_DEVICE_ADDRESS,mDevAdd);
bundle.putString(EXTRAS_DEVICE_NAME,mDeviceName);
if(D) Log.d(TAG,"bundle is--------------:\n"+bundle.toString());
mFragmentTabHost.addTab(spec, mFragments[i], bundle);
} else {
mFragmentTabHost.addTab(spec, mFragments[i], null);
}
mFragmentTabHost.getTabWidget().getChildAt(i).setBackgroundResource(R.drawable.tab_indicator_selector);
}
}
private View getIndicatorView(int i) {
View view = View.inflate(MainTabActivity.this,R.layout.tab_indicator,null);
TextView titleView = (TextView)view.findViewById(R.id.tab_indicator_title);
ImageView imgView = (ImageView)view.findViewById(R.id.tab_indicator_iron);
titleView.setText(mIndicators[i]);
imgView.setBackground(getResources().getDrawable(mIndicatorsIron[i]));
return view;
}
其中mFragmentTabHost的 方法addTab,可以初始化进入Fragment时的arguments。另外,你可以在你当前的Activity中根据spec来确定子Fragment:
HeartRateFragment frag = (HeartRateFragment)getSupportFragmentManager()
.findFragmentByTag(mIndicators[1]);
七. 播放提示音。
首先在你的asserts文件中加入音频文件。
AssertManager assertMng = context.getAsserts();
try {
AssertFileDescriptor afdp = assertMng.openFd("music/beat.mp3);
MediaPlayer mp = new MediaPlayer();
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.realse();
}
});
mp.setAudioStreamType(AudioManager.STREAM_ALARM);
mp.reset();
mp.setDataResource(afDp.getFileDescriptor(),afDp.getStartOffset(),afDp.getLength());
mp.prepare();
mp.start();
}catch(IOException e) {
e.printStackTrace();
}
八. WebView的使用:
mWb = (WebView)mView.findViewById(R.id.rate_web_view);
WebSettings wbSettings = mWb.getSettings();
wbSettings.setJavaScriptEnabled(true);
wbSettings.setAllowFileAccessFromFileURLs(true);
wbSettings.setAllowFileAccess(true);
wbSettings.setAllowContentAccess(true);
wbSettings.setSupportZoom(true);
wbSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
wbSettings.setNeedInitialFocus(true);
//mWebView.getSettings().setUseWideViewPort(true);
// mWebView.getSettings().setLoadWithOverviewMode(true);
// mWebView.setInitialScale(100);
mWb.loadUrl("file:///android_asset/web/heart_line_chart.html");
mWb.setWebViewClient(new WebViewClient(){
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
mWb.loadUrl("javascript:setTitle('" + getActivity().getString(R.string
.rate_chart_title) + "')");
}
});
九. 旋转动画的实现
首先定义一个ImageView:
<RelativeLayout
android:id="@+id/activity_main"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.goertek.asp.tts.MainActivity">
<ImageView
android:id="@+id/pic"
android:src="@drawable/girl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</RelativeLayout>
定义动画,在anim资源文件下:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:duration="5000"
android:repeatCount="-1"
android:pivotX="50%"
android:pivotY="50%">
</rotate>
</set>
在Activity中实现Java代码:
mPic = (ImageView)findViewById(R.id.pic);
Animation animation = mPic.getAnimation();
if(animation==null) {
animation = AnimationUtils.loadAnimation(this,R.anim.my_animation);
LinearInterpolator lin = new LinearInterpolator();
animation.setInterpolator(lin);
}
mPic.startAnimation(animation);
setInterpolator表示设置旋转速率。LinearInterpolator为匀速效果,Accelerateinterpolator为加速效果、DecelerateInterpolator为减速效果,具体可见下面android:interpolator的介绍。
android:fromDegrees 起始的角度度数
android:toDegrees 结束的角度度数,负数表示逆时针,正数表示顺时针。如10圈则比android:fromDegrees大3600即可
android:pivotX 旋转中心的X坐标
浮点数或是百分比。浮点数表示相对于Object的左边缘,如5; 百分比表示相对于Object的左边缘,如5%; 另一种百分比表示相对于父容器的左边缘,如5%p; 一般设置为50%表示在Object中心
android:pivotY 旋转中心的Y坐标
浮点数或是百分比。浮点数表示相对于Object的上边缘,如5; 百分比表示相对于Object的上边缘,如5%; 另一种百分比表示相对于父容器的上边缘,如5%p; 一般设置为50%表示在Object中心
android:duration 表示从android:fromDegrees转动到android:toDegrees所花费的时间,单位为毫秒。可以用来计算速度。
android:interpolator表示变化率,但不是运行速度。一个插补属性,可以将动画效果设置为加速,减速,反复,反弹等。默认为开始和结束慢中间快,
android:startOffset 在调用start函数之后等待开始运行的时间,单位为毫秒,若为10,表示10ms后开始运行
android:repeatCount 重复的次数,默认为0,必须是int,可以为-1表示不停止
android:repeatMode 重复的模式,默认为restart,即重头开始重新运行,可以为reverse即从结束开始向前重新运行。在android:repeatCount大于0或为infinite时生效
android:detachWallpaper 表示是否在壁纸上运行
android:zAdjustment 表示被animated的内容在运行时在z轴上的位置,默认为normal。
normal保持内容当前的z轴顺序
top运行时在最顶层显示
bottom运行时在最底层显示
十. TTS:
mTextToSpeech = new TextToSpeech(MainActivity.this, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if(status==TextToSpeech.SUCCESS) {
int state = mTextToSpeech.setLanguage(Locale.ENGLISH);
if(state==TextToSpeech.LANG_MISSING_DATA||state==TextToSpeech
.LANG_NOT_SUPPORTED) {
mTextToSpeech.setLanguage(Locale.ENGLISH);
}
}
}
});
mTextToSpeech.speak(getString(R.string.speak_content),TextToSpeech.QUEUE_FLUSH, null,UUID.randomUUID().toString());
十一:图片轮番播:
在drawable中定义:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@mipmap/music_anim1" android:duration="200" />
<item android:drawable="@mipmap/music_anim2" android:duration="200" />
<item android:drawable="@mipmap/music_anim3" android:duration="200" />
<item android:drawable="@mipmap/music_anim4" android:duration="200" />
<item android:drawable="@mipmap/music_anim5" android:duration="200" />
<item android:drawable="@mipmap/music_anim6" android:duration="200" />
<item android:drawable="@mipmap/music_anim7" android:duration="200" />
<item android:drawable="@mipmap/music_anim8" android:duration="200" />
<item android:drawable="@mipmap/music_anim9" android:duration="200" />
<item android:drawable="@mipmap/music_anim10" android:duration="200" />
<item android:drawable="@mipmap/music_anim11" android:duration="200" />
<item android:drawable="@mipmap/music_anim12" android:duration="200" />
<item android:drawable="@mipmap/music_anim13" android:duration="200" />
<item android:drawable="@mipmap/music_anim14" android:duration="200" />
<item android:drawable="@mipmap/music_anim15" android:duration="200" />
<item android:drawable="@mipmap/music_anim16" android:duration="200" />
<item android:drawable="@mipmap/music_anim17" android:duration="200" />
<item android:drawable="@mipmap/music_anim18" android:duration="200" />
<item android:drawable="@mipmap/music_anim17" android:duration="200" />
<item android:drawable="@mipmap/music_anim17" android:duration="200" />
<item android:drawable="@mipmap/music_anim18" android:duration="200" />
</animation-list>
private AnimationDrawable mMusicAnimation;// 动画实例
private RelativeLayout mMusicLayout;//动画的载体
//初始化载体。
mMusicLayout = (RelativeLayout)mView.findViewById(R.id.music_relative_layout);
//为载体设置动画
mMusicLayout.setBackgroundResource(R.drawable.music_anim);
mMusicAnimation = (AnimationDrawable)mMusicLayout.getBackground();
//关闭动画
if(mMusicAnimation!=null) {
if(mMusicAnimation.isRunning())
mMusicAnimation.stop();
}
//打开动画
if(mMusicAnimation!=null)
mMusicAnimation.start();