Browse Source

初始化 抽离的bluetooth项目library

leijie 9 years ago
parent
commit
2f6eb2d047
23 changed files with 1765 additions and 0 deletions
  1. 5 0
      ipu-bluetooth/.gitignore
  2. 11 0
      ipu-bluetooth/AndroidManifest.xml
  3. 20 0
      ipu-bluetooth/proguard-project.txt
  4. 17 0
      ipu-bluetooth/res/drawable/share_apk_activity_dialog.xml
  5. 77 0
      ipu-bluetooth/res/layout/share_apk_activity.xml
  6. 39 0
      ipu-bluetooth/res/layout/share_apk_device_list_item.xml
  7. 11 0
      ipu-bluetooth/res/values-v11/styles.xml
  8. 12 0
      ipu-bluetooth/res/values-v14/styles.xml
  9. 115 0
      ipu-bluetooth/res/values/strings.xml
  10. 10 0
      ipu-bluetooth/res/values/strings_share_apk.xml
  11. 7 0
      ipu-bluetooth/res/values/style_share_apk.xml
  12. 20 0
      ipu-bluetooth/res/values/styles.xml
  13. 98 0
      ipu-bluetooth/src/com/ai/ipu/bluetooth/activity/BluetoothPicker.java
  14. 290 0
      ipu-bluetooth/src/com/ai/ipu/bluetooth/activity/ShareByBluetoothActivity.java
  15. 414 0
      ipu-bluetooth/src/com/ai/ipu/bluetooth/func/MobileNetWork.java
  16. 29 0
      ipu-bluetooth/src/com/ai/ipu/bluetooth/listener/OnBondStateChangedListener.java
  17. 38 0
      ipu-bluetooth/src/com/ai/ipu/bluetooth/listener/OnOpenBluetoothListener.java
  18. 21 0
      ipu-bluetooth/src/com/ai/ipu/bluetooth/listener/OnSearchDeviceListener.java
  19. 81 0
      ipu-bluetooth/src/com/ai/ipu/bluetooth/receiver/BondBluetoothReceiver.java
  20. 57 0
      ipu-bluetooth/src/com/ai/ipu/bluetooth/receiver/OpenBluetoothReceiver.java
  21. 51 0
      ipu-bluetooth/src/com/ai/ipu/bluetooth/receiver/ScanBluetoothReceiver.java
  22. 9 0
      ipu-bluetooth/src/com/ai/ipu/bluetooth/util/BluetoothConstant.java
  23. 333 0
      ipu-bluetooth/src/com/ai/ipu/bluetooth/util/BluetoothTool.java

+ 5 - 0
ipu-bluetooth/.gitignore

@ -0,0 +1,5 @@
1
/bin/
2
/.classpath
3
/gen/
4
/.project
5
/project.properties

+ 11 - 0
ipu-bluetooth/AndroidManifest.xml

@ -0,0 +1,11 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
    package="com.ai.ipu.bluetooth"
4
    android:versionCode="1"
5
    android:versionName="1.0" >
6
7
    <uses-sdk
8
        android:minSdkVersion="8"
9
        android:targetSdkVersion="15" />
10
11
</manifest>

+ 20 - 0
ipu-bluetooth/proguard-project.txt

@ -0,0 +1,20 @@
1
# To enable ProGuard in your project, edit project.properties
2
# to define the proguard.config property as described in that file.
3
#
4
# Add project specific ProGuard rules here.
5
# By default, the flags in this file are appended to flags specified
6
# in ${sdk.dir}/tools/proguard/proguard-android.txt
7
# You can edit the include path and order by changing the ProGuard
8
# include property in project.properties.
9
#
10
# For more details, see
11
#   http://developer.android.com/guide/developing/tools/proguard.html
12
13
# Add any project specific keep options here:
14
15
# If your project uses WebView with JS, uncomment the following
16
# and specify the fully qualified class name to the JavaScript interface
17
# class:
18
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19
#   public *;
20
#}

+ 17 - 0
ipu-bluetooth/res/drawable/share_apk_activity_dialog.xml

@ -0,0 +1,17 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<shape xmlns:Android="http://schemas.android.com/apk/res/android" >
3

4
    <padding
5
        Android:bottom="5dp"
6
        Android:left="5dp"
7
        Android:right="5dp"
8
        Android:top="5dp" />
9
	<!-- 外边线 -->
10
    <stroke
11
        Android:width="2dip"
12
        Android:color="#544649" />
13
	
14
    <corners Android:radius="5dp" />
15
	<!-- 内线 -->
16
    <solid Android:color="#8A7479" />
17
</shape>

+ 77 - 0
ipu-bluetooth/res/layout/share_apk_activity.xml

@ -0,0 +1,77 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    android:layout_width="300dp"
4
    android:layout_height="400dp"
5
    android:background="#060514"
6
    android:orientation="vertical" >
7
    
8
    <TextView
9
        android:id="@+id/share"
10
        android:layout_width="match_parent"
11
        android:layout_height="wrap_content"
12
        android:gravity="center"
13
        android:text="@string/sa_share"
14
        android:textColor="#FFFFFF"
15
        android:textSize="20sp" />
16

17
    <View
18
        android:layout_width="match_parent"
19
        android:layout_height="1dp"
20
        android:layout_marginBottom="2dp"
21
        android:layout_marginTop="2dp"
22
        android:background="#696969" />
23

24
    <ListView
25
        android:id="@+id/deviceListView"
26
        android:layout_width="match_parent"
27
        android:layout_height="0dp"
28
        android:layout_weight="1"
29
        android:isScrollContainer="true"
30
        android:paddingTop="5dp" >
31
    </ListView>
32

33
    <View
34
        android:layout_width="match_parent"
35
        android:layout_height="1dp"
36
        android:layout_marginBottom="2dp"
37
        android:layout_marginTop="2dp"
38
        android:background="#696969" />
39

40
    <RelativeLayout
41
        android:layout_width="wrap_content"
42
        android:layout_height="50dp" >
43

44
        <Button
45
            android:id="@+id/exit"
46
            android:layout_width="140dp"
47
            android:layout_height="wrap_content"
48
            android:layout_marginRight="5dp"
49
            android:paddingLeft="20dp"
50
            android:text="@string/sa_exit"
51
            android:textColor="#FFFFFF"
52
            android:textSize="20sp" />
53

54
        <View
55
            android:layout_width="1dip"
56
            android:layout_height="50dp"
57
            android:layout_gravity="center_horizontal"
58
            android:layout_centerInParent="true"
59
            android:background="#696969"
60
            android:layout_marginLeft="3dp"
61
            android:layout_marginRight="3dp"
62
             />
63

64
        <Button
65
            android:id="@+id/search"
66
            android:layout_width="140dp"
67
            android:layout_height="wrap_content"
68
            android:layout_alignParentRight="true"
69
            android:layout_alignTop="@id/exit"
70
            android:layout_marginRight="5dp"
71
            android:paddingRight="20dp"
72
            android:text="@string/sa_search"
73
            android:textColor="#FFFFFF"
74
            android:textSize="20sp" />
75
    </RelativeLayout>
76

77
</LinearLayout>

+ 39 - 0
ipu-bluetooth/res/layout/share_apk_device_list_item.xml

@ -0,0 +1,39 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    android:layout_width="fill_parent"
4
    android:layout_height="fill_parent"
5
    android:orientation="horizontal" >
6

7
    <LinearLayout
8
        android:layout_width="0dp"
9
        android:layout_height="wrap_content"
10
        android:orientation="vertical"
11
        android:layout_weight="1"
12
        android:paddingBottom="5dp"
13
         >
14
        <!-- 设备名 -->
15
        <TextView
16
            android:id="@+id/deviceNameTV"
17
            android:layout_width="wrap_content"
18
            android:layout_height="wrap_content"
19
            android:paddingLeft="5dp"
20
            android:textColor="#fff"
21
            android:textSize="20sp" />
22
        <LinearLayout
23
            android:layout_width="fill_parent"
24
            android:layout_height="wrap_content"
25
            android:orientation="horizontal" >
26
            <!-- MAC地址 -->
27
            <TextView
28
                android:layout_width="wrap_content"
29
                android:layout_height="wrap_content"
30
                android:layout_marginLeft="15dp"
31
                android:text="@string/sa_mac_address" />
32
            <!-- MAC地址字符串 -->
33
            <TextView
34
                android:id="@+id/macAddressTV"
35
                android:layout_width="wrap_content"
36
                android:layout_height="wrap_content" />
37
        </LinearLayout>
38
    </LinearLayout>
39
</LinearLayout>

+ 11 - 0
ipu-bluetooth/res/values-v11/styles.xml

@ -0,0 +1,11 @@
1
<resources>
2
3
    <!--
4
        Base application theme for API 11+. This theme completely replaces
5
        AppBaseTheme from res/values/styles.xml on API 11+ devices.
6
    -->
7
    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
8
        <!-- API 11 theme customizations can go here. -->
9
    </style>
10
11
</resources>

+ 12 - 0
ipu-bluetooth/res/values-v14/styles.xml

@ -0,0 +1,12 @@
1
<resources>
2
3
    <!--
4
        Base application theme for API 14+. This theme completely replaces
5
        AppBaseTheme from BOTH res/values/styles.xml and
6
        res/values-v11/styles.xml on API 14+ devices.
7
    -->
8
    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
9
        <!-- API 14 theme customizations can go here. -->
10
    </style>
11
12
</resources>

+ 115 - 0
ipu-bluetooth/res/values/strings.xml

@ -0,0 +1,115 @@
1
<resources>
2
3
    <string name="app_name">ipu-map</string>
4
    
5
      <string name="action_settings">Settings</string>
6
    
7
    <string name="animate">Animate</string>
8
    <string name="basic_map">基本地图</string>
9
    <string name="basic_description">介绍如何创建一个基本地图</string>
10
    <string name="camera_demo">Camera功能</string>
11
    <string name="camera_description">介绍在地图中操作Camera各种功能</string>
12
    <string name="clear_map">Clear</string>
13
    <string name="compass">指南针</string>
14
    <string name="custom_info_contents">Custom info contents</string>
15
    <string name="custom_info_window">Custom info window</string>
16
    <string name="default_info_window">Default info window</string>
17
    <string name="demo_title">AMaps2D  Demos</string>
18
    <string name="down_arrow">\u2193</string>
19
    <string name="drag_melbourne">Drag Melbourne</string>
20
    <string name="events_demo">Events功能</string>
21
    <string name="events_description">介绍对地图的点击,长按,拖动地图事件功能</string>
22
    <string name="fill_stroke">Fill Stroke</string>
23
    <string name="fill_color">Fill Color</string>
24
    <string name="go_to_zhongguancun">中关村</string>
25
    <string name="go_to_lujiazui">陆家嘴</string>
26
    <string name="hybrid">Hybrid</string>
27
    <string name="location">正在定位中</string>
28
29
    <string-array name="layers_array">
30
        <item>@string/normal</item>
31
        <item>@string/satellite</item>
32
    </string-array>
33
34
    <string name="layers_demo">Layers图层功能</string>
35
    <string name="layers_description">介绍地图分别以正常、卫星模式展示出</string>
36
    <string name="left_arrow">\u2190</string>
37
    <string name="locationsource_demo">Location小蓝点功能</string>
38
    <string name="locationsource_description">介绍对系统定位显示小蓝点功能</string>
39
    <string name="locationGPS_demo">gps定位功能</string>
40
    <string name="locationGPS_description">介绍如何使用gps定位</string>
41
     <string name="locationSensorGPS_demo">gps追随功能</string>
42
      <string name="locationSensorGPS_demo_description">介绍如何用gps定位图标箭头随手机转动而转动</string>
43
    <string name="locationNetwork_description">介绍如何使用网络定位</string>
44
    <string name="locationNetwork_demo">网络定位功能</string>
45
    <string name="marker_demo">Markers功能</string>
46
    <string name="marker_description">介绍在地图上添加marker和infoWindow</string>
47
    <string name="mapOption_demo">AMapOptions实现地图</string>
48
    <string name="mapOption_description">介绍用AMapOptions展示一个地图</string>
49
    <string name="map_not_ready">SupportMapFragment初始化失败</string>
50
    <string name="move_the_camera">移动camera</string>
51
    <string name="my_location">My Location</string>
52
    <string name="mylocation_layer">我的位置图层</string>
53
    <string name="no_demos">No demos</string>
54
    <string name="normal">Normal</string>
55
    <string name="polygon_demo">Polygons功能</string>
56
    <string name="polygon_description">介绍在地图绘制多边形</string>
57
    <string name="polyline_demo">Polylines功能</string>
58
    <string name="polyline_description">介绍在地图中绘制线条</string>
59
    <string name="groundoverlay_demo">GroundOverlay功能</string>
60
    <string name="groundoverlay_description">介绍在地图中绘制GroundOverlay功能</string>
61
    <string name="tileoverlay_demo">TileOverlay功能</string>
62
    <string name="tileoverlay_description">介绍在地图中绘制TileOverlay功能</string>
63
    <string name="circle_demo">Circles功能</string>
64
    <string name="circle_description">介绍在地图中绘制圆形</string>
65
    <string name="screenshot_demo">地图截屏功能</string>
66
    <string name="screenshot_description">介绍对地图进行截屏</string>
67
    <string name="properties_polyline">设置Polyline属性</string>
68
    <string name="properties_polygon">设置Polygon属性</string>
69
    <string name="properties_circle">设置Circle属性</string>
70
    <string name="busline_demo">Busline公交查询</string>
71
    <string name="busline_description">介绍如何在地图中绘制BusLine</string>
72
    <string name="route_demo">Route路径规划</string>
73
    <string name="route_description">介绍如何在地图中绘制Route</string>
74
    <string name="rotate">旋转手势</string>
75
    <string name="reset_map">Reset</string>
76
    <string name="right_arrow">\u2192</string>
77
    <string name="satellite">Satellite</string>
78
    <string name="scroll">滑动手势</string>
79
    <string name="stop_animation">\u25A0</string>
80
    <string name="stroke_width">Stroke Width</string>
81
    <string name="tap_instructions">点击或者长按地图</string>
82
    <string name="terrain">Terrain</string>
83
    <string name="tilt">倾斜手势</string>
84
    <string name="traffic">Traffic</string>
85
    <string name="transparency">Transparency</string>
86
    <string name="uisettings_demo">UI Settings功能</string>
87
    <string name="uisettings_description">介绍地图中UI Settings功能</string>
88
    <string name="geocoder_demo">地理编码 功能</string>
89
    <string name="geocoder_description">介绍 geocoder地理编码 功能</string>
90
    <string name="poikeywordsearch_demo">poi关键字搜索</string>
91
    <string name="poikeywordsearch_description">介绍poi关键字搜索功能</string>
92
    <string name="poiaroundsearch_demo">poi周边搜索</string>
93
    <string name="poiaroundsearch_description">介绍poi周边搜索功能</string>
94
    <string name="offlinemap_demo">离线地图功能</string>
95
    <string name="offlinemap_description">介绍如何使用离线地图</string>
96
    <string name="search_title">搜索关键字</string>
97
    <string name="up_arrow">\u2191</string>
98
    <string name="width">Width</string>
99
    <string name="zoom_buttons">缩放按钮</string>
100
    <string name="zoom_gestures">缩放手势</string>
101
    <string name="zoom_in">+</string>
102
    <string name="zoom_out">-</string>
103
    <string name="scale">比例尺</string>
104
    <string name="buttonScale">获取比例尺</string>
105
    <string name="logo_position">logo位置</string>
106
    <string name="bottom_left">左下</string>
107
    <string name="bottom_center">底部居中</string>
108
    <string name="bottom_right">右下</string>
109
    <string name="map_screenshot">地图截屏</string>
110
    <string name="error_network">搜索失败,请检查网络连接!</string>
111
    <string name="error_key">key验证无效!</string>
112
    <string name="error_other">未知错误,请稍后重试!错误码为</string>
113
    <string name="no_result">对不起,没有搜索到相关数据!</string>
114
115
</resources>

+ 10 - 0
ipu-bluetooth/res/values/strings_share_apk.xml

@ -0,0 +1,10 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<resources>
3
    <string name="sa_share">应用分享</string>
4
	<string name="sa_mac_address">MAC地址:</string>
5
	<string name="sa_search">刷新</string>
6
	<string name="sa_searching">搜索设备中……</string>
7
	<string name="sa_exit">退出</string>
8
	<string name="sa_confirm_share">确认要分享吗?</string>
9
	<string name="sa_tip">请将远程蓝牙设备打开,并且保持可见……</string>
10
</resources>

+ 7 - 0
ipu-bluetooth/res/values/style_share_apk.xml

@ -0,0 +1,7 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<resources>
3
    <style name="ShareApkDialogTheme" parent="@android:style/Theme.Dialog">
4
        <!-- 无标题 -->
5
        <item name="android:windowNoTitle">true</item>
6
    </style>
7
</resources>

+ 20 - 0
ipu-bluetooth/res/values/styles.xml

@ -0,0 +1,20 @@
1
<resources>
2
3
    <!--
4
        Base application theme, dependent on API level. This theme is replaced
5
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
6
    -->
7
    <style name="AppBaseTheme" parent="android:Theme.Light">
8
        <!--
9
            Theme customizations available in newer API levels can go in
10
            res/values-vXX/styles.xml, while customizations related to
11
            backward-compatibility can go here.
12
        -->
13
    </style>
14
15
    <!-- Application theme. -->
16
    <style name="AppTheme" parent="AppBaseTheme">
17
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
18
    </style>
19
20
</resources>

+ 98 - 0
ipu-bluetooth/src/com/ai/ipu/bluetooth/activity/BluetoothPicker.java

@ -0,0 +1,98 @@
1
package com.ai.ipu.bluetooth.activity;
2

3
import android.app.Activity;
4
import android.bluetooth.BluetoothDevice;
5
import android.content.Intent;
6
import android.os.Bundle;
7

8
import com.wade.mobile.ui.helper.HintHelper;
9

10
/**
11
 * @author huangbo
12
	<activity android:name="com.wade.mobile.activity.BluetoothPicker">
13
        <intent-filter>
14
            <action android:name="android.bluetooth.devicepicker.action.LAUNCH" />
15
            <category android:name="android.intent.category.DEFAULT" />
16
        </intent-filter>
17
    </activity>
18
 */
19
public class BluetoothPicker extends Activity {
20
	private String mLaunchPackage;
21
	private String mLaunchClass;
22

23
//	public static final String EXTRA_NEED_AUTH = "android.bluetooth.devicepicker.extra.NEED_AUTH";
24
	public static final String EXTRA_FILTER_TYPE = "android.bluetooth.devicepicker.extra.FILTER_TYPE";
25
	public static final String EXTRA_LAUNCH_PACKAGE = "android.bluetooth.devicepicker.extra.LAUNCH_PACKAGE";
26
	public static final String EXTRA_LAUNCH_CLASS = "android.bluetooth.devicepicker.extra.DEVICE_PICKER_LAUNCH_CLASS";
27

28
	public static final String ACTION_DEVICE_SELECTED = "android.bluetooth.devicepicker.action.DEVICE_SELECTED";
29
	public static final String ACTION_LAUNCH = "android.bluetooth.devicepicker.action.LAUNCH";
30

31
	/** Ask device picker to show all kinds of BT devices */
32
	public static final int FILTER_TYPE_ALL = 0;
33
	/** Ask device picker to show BT devices that support AUDIO profiles */
34
	public static final int FILTER_TYPE_AUDIO = 1;
35
	/** Ask device picker to show BT devices that support Object Transfer */
36
	public static final int FILTER_TYPE_TRANSFER = 2;
37
	
38
	public static BluetoothDevice device;
39
	
40
	@Override
41
	public void onCreate(Bundle savedInstanceState) {
42
		super.onCreate(savedInstanceState);
43
		if (device == null) {
44
			HintHelper.alert(this, "Failed to get selected bluetooth device!");
45
			finish();
46
			return;
47
		}
48

49
		Intent intent = getIntent();
50
		// mNeedAuth = intent.getBooleanExtra(EXTRA_NEED_AUTH, false);
51
		//setFilter(intent.getIntExtra(EXTRA_FILTER_TYPE, FILTER_TYPE_ALL));
52
		mLaunchPackage = intent.getStringExtra(EXTRA_LAUNCH_PACKAGE);
53
		mLaunchClass = intent.getStringExtra(EXTRA_LAUNCH_CLASS);
54

55
		sendDevicePickedIntent(device);
56
		finish();
57
	}
58

59
	private void sendDevicePickedIntent(BluetoothDevice device) {
60
		Intent intent = new Intent(ACTION_DEVICE_SELECTED);
61
		intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
62
		if (mLaunchPackage != null && mLaunchClass != null) {
63
			intent.setClassName(mLaunchPackage, mLaunchClass);
64
		}
65
		sendBroadcast(intent);
66
	}
67
	
68
	@Override
69
	protected void onDestroy() {
70
		// TODO Auto-generated method stub
71
		super.onDestroy();
72
		device = null;
73
	}
74
	
75
	/*public BluetoothDevice getSelectedDevice() {
76
		BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
77

78
		if (!btAdapter.isEnabled()) {
79
			Log.e(TAG, "Bluetooth adapter is not enabled!");
80
			return null;
81
		}
82

83
		Set<BluetoothDevice> devices = btAdapter.getBondedDevices();
84
		Log.i(TAG, "Automatic printer selection");
85

86
		// Take the first printer paired
87
		for (BluetoothDevice itDevice : devices) {
88
			Log.i(TAG, "itDevice : "+itDevice.getAddress()+"|"+itDevice.getName()+"|"+itDevice.getUuids());
89
			//BluetoothClass.Device.Major.IMAGING
90
			if (itDevice.getBluetoothClass().getMajorDeviceClass() == BluetoothClass.Device.Major.PHONE) {
91
				Log.i(TAG, "Using printer " + itDevice.getName() + " selected automatically");
92
				return itDevice;
93
			}
94
		}
95
		Log.e(TAG, "No usable printer!");
96
		return null;
97
	}*/
98
}

+ 290 - 0
ipu-bluetooth/src/com/ai/ipu/bluetooth/activity/ShareByBluetoothActivity.java

@ -0,0 +1,290 @@
1
package com.ai.ipu.bluetooth.activity;
2

3
import java.util.ArrayList;
4
import java.util.List;
5

6
import android.app.Activity;
7
import android.app.AlertDialog;
8
import android.app.ProgressDialog;
9
import android.bluetooth.BluetoothDevice;
10
import android.content.DialogInterface;
11
import android.os.Bundle;
12
import android.os.Handler;
13
import android.os.HandlerThread;
14
import android.view.KeyEvent;
15
import android.view.LayoutInflater;
16
import android.view.View;
17
import android.view.View.OnClickListener;
18
import android.view.ViewGroup;
19
import android.widget.AdapterView;
20
import android.widget.AdapterView.OnItemClickListener;
21
import android.widget.BaseAdapter;
22
import android.widget.Button;
23
import android.widget.ListView;
24
import android.widget.TextView;
25
import android.widget.Toast;
26

27
import com.ai.ipu.bluetooth.R;
28
import com.ai.ipu.bluetooth.listener.OnSearchDeviceListener;
29
import com.ai.ipu.bluetooth.util.BluetoothConstant;
30
import com.ai.ipu.bluetooth.util.BluetoothTool;
31
import com.wade.mobile.app.MobileAppInfo;
32
import com.wade.mobile.ui.helper.HintHelper;
33

34

35
/**
36
 * @author huangbo
37
	<activity 
38
	    android:name="com.wade.mobile.activity.ShareByBluetoothActivity"
39
	    android:theme="@style/shareApkDialogStyle">
40
	    <intent-filter>
41
	        <category android:name="android.intent.category.DEFAULT" />
42
	    </intent-filter>
43
	</activity>
44
 */
45
public class ShareByBluetoothActivity extends Activity {
46
	private Button searchBtn;		//刷新按钮
47
	private Button exitBtn;			//退出按钮
48
	private BluetoothTool tool;	//蓝牙工具类
49
	private boolean initState;
50
	
51
	private List<BluetoothDevice> deviceList;	//蓝牙设备信息列表
52
	private ListView deviceListView;			//蓝牙设备列表视图
53
	
54
	private ProgressDialog mProgressDialog;		//对话框
55
	private Handler bluetoothHandler;
56
	{
57
		HandlerThread handlerThread = new HandlerThread("bluetoothHandler");
58
		handlerThread.start();
59
		bluetoothHandler = new Handler(handlerThread.getLooper());
60
		try{
61
			tool = new BluetoothTool(this);
62
		}catch(Exception e){
63
			e.printStackTrace();
64
			Toast.makeText(getApplicationContext(), "蓝牙初始化出错!", Toast.LENGTH_LONG);
65
			this.finish();
66
		}
67
		initState=tool.isEnabled();//保存进入此界面时,蓝牙的初始状态
68
	}
69
	
70
	/**/
71
	OnItemClickListener deviceListViewItemClickListener = new OnItemClickListener() {
72
		@Override
73
		public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
74
			final BluetoothDevice device = (BluetoothDevice) parent.getItemAtPosition(position);
75
			initAlertDialog(getResources().getString(R.string.sa_confirm_share),
76
					new DialogInterface.OnClickListener() {
77
						public void onClick(DialogInterface dialog, int which) {
78
							try {
79
								MobileAppInfo mAppInfo =  MobileAppInfo.getInstance(ShareByBluetoothActivity.this);
80
								tool.sendFile(mAppInfo.getApk(), device);
81
								setResult(BluetoothConstant.SUC_REQ_SEND_FILE);
82
							} catch (Exception e) {
83
								setResult(BluetoothConstant.ERR_REQ_SEND_FILE);
84
								HintHelper.alert(ShareByBluetoothActivity.this, "文件分享异常:"+e.getMessage());
85
								e.printStackTrace();
86
							}
87
						}
88
					}).show();
89
		}
90
	};
91
	
92
	OnSearchDeviceListener searchDeviceListener = new OnSearchDeviceListener() {
93
		public boolean onFound(BluetoothDevice device) {
94
			if (!deviceList.contains(device)) {
95
				deviceList.add(device);
96
				updateDeviceList();
97
			}
98
			return false;
99
		}
100

101
		public void onFinished() {
102
			closeDialog();
103
		}
104
	};
105

106
	@Override
107
	protected void onCreate(Bundle savedInstanceState) {
108
		super.onCreate(savedInstanceState);
109
		setContentView(R.layout.share_apk_activity);
110
		// 初始化button
111
		searchBtn = (Button) findViewById(R.id.search);
112
		exitBtn = (Button) findViewById(R.id.exit);
113
		searchBtn.setOnClickListener(new OnClickListener() {
114
			public void onClick(View v) {
115
				deviceList.clear();
116
				findDevices();//搜索蓝牙设备
117
			}
118
		});
119
		exitBtn.setOnClickListener(new OnClickListener() {
120
			public void onClick(View v) {
121
				finish();
122
			}
123
		});
124
		//旋转时获取存储的设备列表
125
		if (deviceList == null){
126
			if(getLastNonConfigurationInstance()==null){
127
				deviceList = new ArrayList<BluetoothDevice>();
128
			}else{
129
				deviceList = (List<BluetoothDevice>) getLastNonConfigurationInstance();
130
			}
131
		}
132
		// 初始化蓝牙设备列表
133
		deviceListView = (ListView) findViewById(R.id.deviceListView);
134
		deviceListView.setAdapter(new DeviceListAdapter(this, deviceList, R.layout.share_apk_device_list_item));
135
		deviceListView.setOnItemClickListener(deviceListViewItemClickListener);
136
		// 如果没有驱动列表,则搜索
137
		if (deviceList.size() == 0) {
138
			Toast.makeText(getApplicationContext(),
139
					getResources().getString(R.string.sa_tip), Toast.LENGTH_LONG)
140
					.show();
141
			if (getIntent().getBooleanExtra(BluetoothConstant.AUTO_SEARCH_KEY, true) && deviceList.size() == 0) {
142
				findDevices();
143
			}
144
		}
145
	}
146

147
	/**
148
	 * 显示所有设备
149
	 */
150
	private void findDevices() {
151
		try {
152
			initDialog(getResources().getString(R.string.sa_searching)).show();
153
			if (tool.isBusy()) {
154
				bluetoothHandler.post(new Runnable() {
155
					public void run() {
156
						try {
157
							while (tool.isBusy()) {
158
								Thread.sleep(500);
159
							}
160
						} catch (InterruptedException e) {
161
						}
162
						tool.searchDevice(searchDeviceListener, true);
163
					}
164
				});
165
			} else {
166
				tool.searchDevice(searchDeviceListener, true);
167
			}
168
			setResult(BluetoothConstant.SUC_REQ_SEARCH);
169
		} catch (Exception e) {
170
			closeDialog();
171
			setResult(BluetoothConstant.ERR_REQ_SEARCH);
172
			HintHelper.alert(ShareByBluetoothActivity.this, "搜索蓝牙设备异常:"+e.getMessage());
173
			e.printStackTrace();
174
		}
175
	}
176

177
	/**
178
	 * 更新设备列表
179
	 */
180
	private void updateDeviceList() {
181
		this.runOnUiThread(new Runnable() {
182
			@Override
183
			public void run() {
184
				// TODO Auto-generated method stub
185
				((BaseAdapter)deviceListView.getAdapter()).notifyDataSetChanged();
186
			}
187
		});
188
	}
189

190
	/**
191
	 * 状态对话框
192
	 * 
193
	 * @return 对话框
194
	 */
195
	private ProgressDialog initDialog(String msg) {
196
		if (null == mProgressDialog) {
197
			mProgressDialog = new ProgressDialog(this);
198
		}
199
		mProgressDialog.setMessage(msg);
200
		return mProgressDialog;
201
	}
202

203
	/**
204
	 * 关闭对话框
205
	 */
206
	private void closeDialog() {
207
		if (null != mProgressDialog) {
208
			mProgressDialog.dismiss();
209
		}
210
	}
211

212
	/**
213
	 * 初始化警告对话框
214
	 */
215
	private AlertDialog.Builder initAlertDialog(String msg,
216
			DialogInterface.OnClickListener dialogListener) {
217
		return new AlertDialog.Builder(this).setTitle("确认").setMessage(msg)
218
				.setPositiveButton("是", dialogListener)
219
				.setNegativeButton("否", null);
220
	}
221

222
	public boolean onKeyDown(int keyCode, KeyEvent event) {
223
		if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
224
			finish();
225
		}
226
		return super.onKeyDown(keyCode, event);
227
	}
228
	
229
	@Override
230
	protected void onDestroy() {
231
		super.onDestroy();
232
		//如果开始蓝牙是关闭的,现在的蓝牙是打开的,则,关闭蓝牙设备。
233
		if (tool.isEnabled() && !initState) {
234
			//判断开始时蓝牙状态
235
			tool.closeBluetooth();//关闭蓝牙
236
		}
237
		tool = null;
238
		bluetoothHandler = null;
239
	}
240
	
241
	@Override
242
	@Deprecated
243
	public Object onRetainNonConfigurationInstance() {
244
		// TODO Auto-generated method stub
245
		return deviceList;//存储屏幕旋转时的数据
246
	}
247
	
248
	/**
249
	 * 蓝牙驱动列表适配器
250
	 */
251
	public static class DeviceListAdapter extends BaseAdapter {
252
		private Activity mActivity;
253
		private List<BluetoothDevice> mDeviceList;
254
		private int mLayoutId;
255

256
		public DeviceListAdapter(Activity activity, List<BluetoothDevice> deviceList, int layoutId) {
257
			this.mDeviceList = deviceList;
258
			this.mActivity = activity;
259
			this.mLayoutId = layoutId;
260
		}
261

262
		@Override
263
		public int getCount() {
264
			return mDeviceList.size();
265
		}
266

267
		@Override
268
		public Object getItem(int position) {
269
			return mDeviceList.get(position);
270
		}
271

272
		@Override
273
		public long getItemId(int position) {
274
			return position;
275
		}
276

277
		@Override
278
		public View getView(int position, View convertView, ViewGroup parent) {
279
			BluetoothDevice bluetoothDevice = mDeviceList.get(position);
280
			if(convertView==null){
281
				convertView = LayoutInflater.from(mActivity).inflate(mLayoutId, null);
282
			}
283
			TextView mDeviceNameTV = (TextView) convertView.findViewById(R.id.deviceNameTV);
284
			TextView mMacAddressTV = (TextView) convertView.findViewById(R.id.macAddressTV);
285
			mDeviceNameTV.setText(bluetoothDevice.getName());
286
			mMacAddressTV.setText(bluetoothDevice.getAddress());
287
			return convertView;
288
		}
289
	}
290
}

+ 414 - 0
ipu-bluetooth/src/com/ai/ipu/bluetooth/func/MobileNetWork.java

@ -0,0 +1,414 @@
1
package com.ai.ipu.bluetooth.func;
2

3
import java.io.File;
4
import java.io.InputStream;
5
import java.util.HashMap;
6
import java.util.HashSet;
7
import java.util.Map;
8

9
import org.json.JSONArray;
10

11
import android.bluetooth.BluetoothAdapter;
12
import android.content.Intent;
13
import android.net.Uri;
14
import android.os.AsyncTask;
15
import android.os.Build;
16
import android.widget.Toast;
17

18
import com.ai.ipu.bluetooth.activity.ShareByBluetoothActivity;
19
import com.ai.ipu.bluetooth.listener.OnOpenBluetoothListener;
20
import com.ai.ipu.bluetooth.util.BluetoothTool;
21
import com.ailk.common.data.IData;
22
import com.ailk.common.data.impl.DataMap;
23
import com.litesuits.http.LiteHttpClient;
24
import com.litesuits.http.request.Request;
25
import com.litesuits.http.response.Response;
26
import com.wade.mobile.app.MobileAppInfo;
27
import com.wade.mobile.common.MobileThread;
28
import com.wade.mobile.common.sms.listener.OnSmsReceiveListener;
29
import com.wade.mobile.common.sms.util.SmsTool;
30
import com.wade.mobile.frame.IWadeMobile;
31
import com.wade.mobile.frame.config.MobileConfig;
32
import com.wade.mobile.frame.config.ServerDataConfig;
33
import com.wade.mobile.frame.plugin.Plugin;
34
import com.wade.mobile.safe.MobileSecurity;
35
import com.wade.mobile.util.BusinessCache;
36
import com.wade.mobile.util.Constant;
37
import com.wade.mobile.util.DirectionUtil;
38
import com.wade.mobile.util.FileUtil;
39
import com.wade.mobile.util.FuncConstant;
40
import com.wade.mobile.util.Messages;
41
import com.wade.mobile.util.StringUtil;
42
import com.wade.mobile.util.Utility;
43
import com.wade.mobile.util.http.HttpTool;
44
import com.wade.mobile.util.http.UnirestUtil;
45

46
public class MobileNetWork extends Plugin {
47
	private boolean hasSetSmsListener;
48
	private DirectionUtil directionUtil;
49

50
	public MobileNetWork(IWadeMobile wademobile) {
51
		super(wademobile);
52
		directionUtil = DirectionUtil.getInstance(context);
53
	}
54

55
	public void setSmsListener(JSONArray param) throws Exception {
56
		String telString = param.getString(0);
57
		setSmsListener(telString);
58
	}
59

60
	public void setSmsListener(String telString) throws Exception {
61
		HashSet<String> telSet = null;
62
		if(!isNull(telString)){
63
			telSet = new HashSet<String>();
64
			if(StringUtil.isJSONArray(telString)) {
65
				JSONArray teles = new JSONArray(telString);
66
				for(int i=0; i <teles.length() ; i++){
67
					telSet.add(teles.getString(i));
68
				}
69
			} else {
70
				telSet.add(telString);
71
			}
72
		}
73
		
74
		final HashSet<String> _telSet = telSet;
75
		if (!hasSetSmsListener) {
76
			SmsTool.setSmsListener(context, new OnSmsReceiveListener() {
77
				@Override
78
				public boolean onSmsReceive(String content, String sender, long time) {
79
					if (_telSet == null || _telSet.contains(sender)) {// 没有滤号码或者存在过滤号码均处理
80
						IData resultData = new DataMap();
81
						resultData.put(FuncConstant.CONTENT, content);
82
						resultData.put(FuncConstant.SENDER, sender);
83
						resultData.put(FuncConstant.TIME, time);
84
						String result = resultData.toString();
85
						callback(result, true);
86
						hasSetSmsListener = false;
87
						return true;
88
					} else {
89
						return false;
90
					}
91
				}
92
			});
93
			hasSetSmsListener = true;
94
		}
95
	}
96

97
	public void httpRequest(JSONArray param) throws Exception {
98
		String requestUrl = param.getString(0);
99
		String encode = param.getString(1);
100
		if (isNull(encode)) {
101
			encode = MobileConfig.getInstance().getEncode();
102
		}
103
		String result;
104
		try {
105
			result = httpRequest(requestUrl, encode);
106
		} catch (Exception e) {
107
			result = "{\"X_RESULTCODE\":\"-1\",\"X_RESULTINFO\":\"" + e.getMessage() + "\"}";
108
		}
109
		callback(result, true);
110
	}
111

112
	public String httpRequest(String requestUrl, String encode) throws Exception {
113
		// TODO Auto-generated method stub
114
		MobileConfig config = MobileConfig.getInstance();
115
		// 预处理
116
		if (!requestUrl.startsWith(Constant.HTTP)) {
117
			if (!requestUrl.startsWith("/"))
118
				requestUrl = "/" + requestUrl;
119
			requestUrl = config.getRequestHost() + requestUrl;
120
		}
121

122
		requestUrl = HttpTool.urlEncode(requestUrl, encode);
123
		return HttpTool.httpRequest(requestUrl, null, Constant.HTTP_POST, encode);
124
	}
125

126
	public void httpGet(JSONArray param) throws Exception {
127
		String requestUrl = param.getString(0);
128
		String encode = param.getString(1);
129
		if (isNull(encode)) {
130
			encode = MobileConfig.getInstance().getEncode();// UTF-8
131
		}
132
		String result;
133

134
		try {
135
			/* 方式1 */
136
			/*result = httpGet(requestUrl,encode);*/
137
			/* 方式2 */
138
			LiteHttpClient client = LiteHttpClient.getInstance(context);
139
			Response res = client.execute(new Request(requestUrl));
140
			result = res.getString();
141
		} catch (Exception e) {
142
			result = e.getMessage();
143
		}
144
		callback(result, true);
145
	}
146

147
	public String httpGet(String requestUrl, String encode) throws Exception {
148
		MobileConfig config = MobileConfig.getInstance();
149
		/* 预处理 */
150
		if (!requestUrl.startsWith(Constant.HTTP)) {
151
			if (!requestUrl.startsWith("/"))
152
				requestUrl = "/" + requestUrl;
153
			requestUrl = config.getRequestHost() + requestUrl;
154
		}
155

156
		requestUrl = HttpTool.urlEncode(requestUrl, encode);
157
		return HttpTool.httpRequest(requestUrl, null, Constant.HTTP_GET, encode);
158
	}
159

160
	public void dataRequest(JSONArray param) throws Exception {
161
		String dataAction = param.getString(0);
162
		String data = param.getString(1);
163
		String result = dataRequest(dataAction, isNull(data) ? null : new DataMap(data));
164
		callback(result, true);
165
	}
166

167
	/**
168
	 * @param dataAction
169
	 * @param param
170
	 * @param isMustEncrypt
171
	 *            是否一定加密传输
172
	 * @return
173
	 * @throws Exception
174
	 */
175
	public String dataRequest(String dataAction, IData param) throws Exception {
176
		synchronized (dataAction) {
177
			String result = (String) BusinessCache.getInstance().get(dataAction);
178
			if (result != null) {
179
				BusinessCache.getInstance().remove(dataAction);
180
			} else {
181
				result = requestBizData(dataAction, param);
182
			}
183
			return result;
184
		}
185
	}
186

187
	private String requestBizData(String dataAction, IData param) throws Exception {
188
		Map<String,String> postData = transPostData(dataAction, param);
189
		String dataUrl = HttpTool.toQueryStringWithEncode(postData);
190
		String result = HttpTool.httpRequest(MobileConfig.getInstance().getRequestUrl(),
191
				dataUrl, Constant.HTTP_POST);
192
		if (ServerDataConfig.isEncrypt(dataAction)) {
193
			result = MobileSecurity.responseDecrypt(result);
194
		}
195
		return result;
196
	}
197
	
198
	public Map<String, String> transPostData(String dataAction, IData dataParam) throws Exception {
199
		// TODO Auto-generated method stub
200
		Map<String, String> postData = new HashMap<String, String>();
201
		postData.put(Constant.Server.ACTION, dataAction);
202
		if (ServerDataConfig.isEncrypt(dataAction)) {
203
			MobileSecurity.init(context);
204
			/* 参数加密处理 */
205
			String key = MobileSecurity.getDesKey();
206
			postData.put(Constant.Server.KEY, key);
207
			
208
			if(dataParam!=null){
209
				String encryptData = MobileSecurity.requestEncrypt(dataParam.toString());
210
				postData.put(Constant.Server.DATA, encryptData);
211
			}
212
		} else {
213
			if (dataParam != null) {
214
				postData.put(Constant.Server.DATA, dataParam.toString());
215
			}
216
		}
217
		return postData;
218
	}
219

220
	public void storageDataByThread(JSONArray param) throws Exception {
221
		String dataAction = param.getString(0);
222
		String data = param.getString(1);
223
		boolean isEncrypt = false;
224
		if (param.length() > 2) {
225
			isEncrypt = "true".equals(param.getString(2)) ? true : false;
226
		}
227

228
		int waitoutTime = 5;
229
		if (param.length() > 3) {
230
			waitoutTime = param.getInt(3);
231
		}
232
		storageDataByThread(dataAction, isNull(data) ? null : new DataMap(data), isEncrypt, waitoutTime);
233
	}
234

235
	public void storageDataByThread(final String dataAction, final IData param,
236
			final boolean isEncrypt, long waitoutTime) throws Exception {
237
		waitoutTime = (waitoutTime < 3 || waitoutTime > 10) ? 5 : waitoutTime;// 修正waitoutTime,确保在一定范围
238
		new MobileThread(dataAction, waitoutTime) {
239
			@Override
240
			protected void execute() throws Exception {
241
				String result = requestBizData(dataAction, param);
242
				synchronized (dataAction) {
243
					BusinessCache.getInstance().put(dataAction, result);
244
				}
245
			}
246
		}.start();
247
	}
248

249
	public void shareByBluetooth(JSONArray param) throws Exception {
250
		try {
251
			BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
252
			if (adapter == null) {
253
				Toast.makeText(context, "蓝牙初始化出错!", Toast.LENGTH_LONG);
254
				return;
255
			}
256
		} catch (Exception e) {
257
			Toast.makeText(context, "蓝牙初始化出错!", Toast.LENGTH_LONG);
258
			return;
259
		}
260

261
		if (Build.VERSION.SDK_INT < MobileAppInfo.Android_4_1_2) {
262
			try {
263
				Intent intent = new Intent(context, ShareByBluetoothActivity.class);
264
				context.startActivity(intent);
265
			} catch (Exception e) {
266
				e.printStackTrace();
267
				Toast.makeText(context, "蓝牙初始化出错!", Toast.LENGTH_LONG);
268
			}
269
		} else {
270
			final BluetoothTool bluetoothTools = new BluetoothTool(context);
271
			final MobileAppInfo mobileAppInfo = MobileAppInfo.getInstance(context);
272
			if (bluetoothTools.isEnabled()) {
273
				bluetoothTools.sendFile(mobileAppInfo.getApk());
274
			} else {
275
				bluetoothTools.openBluetooth(new OnOpenBluetoothListener() {
276
					public void OnOpened(BluetoothAdapter adapter) {
277
						// 开始查找设备。
278
						try {
279
							bluetoothTools.sendFile(mobileAppInfo.getApk());
280
						} catch (Exception e) {
281
							e.printStackTrace();
282
						}
283
					}
284
				});
285
			}
286
		}
287
	}
288
	/**
289
	 * 打开浏览器
290
	 */
291
	public void openBrowser(JSONArray param) throws Exception {
292
		String url = param.getString(0);
293
		openBrowser(url);
294
	}
295
	/**
296
	 * 打开浏览器
297
	 */
298
	public void openBrowser(String url) {
299
		Uri uri = Uri.parse(url);
300
		Intent intent = new Intent(Intent.ACTION_VIEW, uri);
301
		context.startActivity(intent);
302
	}
303
	
304
	public void uploadWithServlet(JSONArray param) throws Exception {
305
		JSONArray filePaths = param.getJSONArray(0);
306
		String dataAction = param.getString(1);
307
		IData dataParam = isNull(param.getString(2))?new DataMap():new DataMap(param.getString(2));
308
		uploadWithServlet(filePaths, dataAction, dataParam);
309
	}
310
	
311
	@SuppressWarnings("unchecked")
312
	public void uploadWithServlet(final JSONArray filePaths, final String dataAction, IData dataParam) throws Exception {
313
		// TODO Auto-generated method stub
314
		Map<String, String> postData = transPostData(dataAction, dataParam);
315
		new AsyncTask<Map<String, String>, Integer, String>() {
316
			@Override
317
			protected String doInBackground(Map<String, String>... args) {
318
				Map<String, String> postData = args[0];
319
				Map<String, Object> fileData = new HashMap<String, Object>();
320
				// TODO Auto-generated method stub
321
				String result = null;
322
				try{
323
					String filePath = null;
324
					File file;
325
					for(int i=0;i<filePaths.length();i++){
326
						filePath = filePaths.getString(i);
327
						file = new File(filePath);
328
						if(!file.exists()){
329
							Utility.error(Messages.FILE_NOT_EXIST+":"+filePath);
330
						}
331
						fileData.put("UPLOAD_FILE"+i, file);//装载文件
332
					}
333
					fileData.put("UPLOAD_FILE_COUNT", filePaths.length());//装载文件数量
334
					
335
					String encode = MobileConfig.getInstance().getEncode();
336
					String dataUrl = HttpTool.urlEncode(HttpTool.toQueryString(postData), encode);
337
					String url = MobileConfig.getInstance().getRequestUrl() + "?" + dataUrl;
338
					result = UnirestUtil.uploadByPost(HttpTool.urlEscape(url).toString(), fileData);
339
					if (ServerDataConfig.isEncrypt(dataAction)) {
340
						result = MobileSecurity.responseDecrypt(result);
341
					}
342
				}catch(Exception e){
343
					MobileNetWork.this.error(e.getMessage());// 报错回调
344
					Utility.error(e);
345
				}
346
				return result;
347
			}
348
			
349
			@Override
350
			protected void onPostExecute(String result) {
351
				// TODO Auto-generated method stub
352
				super.onPostExecute(result);
353
				if (result != null) {
354
					MobileNetWork.this.callback(result, true);// 正常回调
355
				}
356
			}
357
		}.execute(postData);
358
	}
359
	
360
	public void downloadWithServlet(JSONArray param) throws Exception {
361
		String savePath = param.getString(0);
362
		String dataAction = param.getString(1);
363
		IData dataParam = param.getString(2) == null ? new DataMap() : new DataMap(param.getString(2));
364
		downloadWithServlet(savePath, dataAction, dataParam);
365
	}
366
	
367
	public void downloadWithServlet(final String _savePath, String dataAction, IData dataParam) throws Exception {
368
		// TODO Auto-generated method stub
369
		Map<String, String> tempPostData = transPostData(dataAction, dataParam);
370
		final Map<String, Object> postData = new HashMap<String, Object>();
371
		postData.putAll(tempPostData);
372
		new AsyncTask<String, Integer, String>() {
373
			@Override
374
			protected String doInBackground(String... arg0) {
375
				// TODO Auto-generated method stub
376
				String savePath = _savePath;
377
				try {
378
					InputStream in = UnirestUtil.downloadByPost(MobileConfig.getInstance().getRequestUrl(), postData);
379
					if (!savePath.startsWith(File.separator)) {
380
						savePath = directionUtil.getDirection(savePath, true);
381
					}
382
					File file = new File(savePath).getParentFile();
383
					if (!file.exists() && !file.mkdirs()) {
384
						Utility.error("创建下载文件夹失败!");
385
					}
386

387
					FileUtil.writeFile(in, savePath);
388
				} catch (Exception e) {
389
					MobileNetWork.this.error("[" + savePath + "]异常:" + e.getMessage());// 报错回调
390
				}
391
				return savePath;
392
			}
393
			
394
			@Override
395
			protected void onPostExecute(String savePath) {
396
				// TODO Auto-generated method stub
397
				super.onPostExecute(savePath);
398
				if (savePath != null) {
399
					MobileNetWork.this.callback(savePath, true);// 正常回调
400
				}
401
			}
402
		}.execute();
403
	}
404

405
	public void uploadFile(JSONArray param) throws Exception {
406
		String path = param.getString(0);
407
		uploadFile(path);
408
	}
409

410
	public void uploadFile(String path) throws Exception {
411
		// TODO Auto-generated method stub
412
		
413
	}
414
}

+ 29 - 0
ipu-bluetooth/src/com/ai/ipu/bluetooth/listener/OnBondStateChangedListener.java

@ -0,0 +1,29 @@
1
package com.ai.ipu.bluetooth.listener;
2

3
import android.bluetooth.BluetoothDevice;
4
/**
5
 * 当蓝牙设备配对状态改变事件监听器
6
 * @author softm
7
 */
8
public abstract class OnBondStateChangedListener {
9
	/**
10
	 * 当状态改变时
11
	 * @param device 改变状态的蓝牙设备
12
	 * @return 返回true时,取消监听。
13
	 */
14
	public abstract boolean onBonded(BluetoothDevice device) throws Exception;
15
	/**
16
	 * 改变状态中
17
	 * @param device 改变状态的蓝牙设备
18
	 * @throws Exception
19
	 */
20
	public void onBonding(BluetoothDevice device) throws Exception{} ;
21
	/**
22
	 * 当请求配对时
23
	 * @param device 当前设备
24
	 * @return 返回true时,自动配对
25
	 */
26
	public boolean onPairingRequest(BluetoothDevice device) throws Exception{
27
		return true;
28
	}
29
}

+ 38 - 0
ipu-bluetooth/src/com/ai/ipu/bluetooth/listener/OnOpenBluetoothListener.java

@ -0,0 +1,38 @@
1
package com.ai.ipu.bluetooth.listener;
2

3
import android.bluetooth.BluetoothAdapter;
4

5
/**
6
 * 蓝牙状态监听器
7
 * @author softm
8
 */
9
public abstract class OnOpenBluetoothListener {
10

11
	/**
12
	 * 打开蓝牙时触发
13
	 * @param adapter
14
	 */
15
	public void OnOpen(BluetoothAdapter adapter) {
16
	};
17

18
	/**
19
	 * 打开蓝牙成功后触发
20
	 * @param adapter
21
	 */
22
	public void OnOpened(BluetoothAdapter adapter) {
23
	};
24

25
	/**
26
	 * 关闭蓝牙时触发
27
	 * @param adapter
28
	 */
29
	public void OnClose(BluetoothAdapter adapter) {
30
	};
31

32
	/**
33
	 * 关闭蓝牙成功后触发
34
	 * @param adapter
35
	 */
36
	public void OnClosed(BluetoothAdapter adapter) {
37
	};
38
}

+ 21 - 0
ipu-bluetooth/src/com/ai/ipu/bluetooth/listener/OnSearchDeviceListener.java

@ -0,0 +1,21 @@
1
package com.ai.ipu.bluetooth.listener;
2

3
import android.bluetooth.BluetoothDevice;
4

5
/**
6
 * 搜索远程蓝牙设备事件监听器
7
 * @author softm
8
 */
9
public abstract class OnSearchDeviceListener {
10
	/**
11
	 * 当搜索到一个远程蓝牙设备时执行此方法
12
	 * @param 当返回true时,取消设备搜索
13
	 */
14
	public abstract boolean onFound(BluetoothDevice device);
15

16
	/**
17
	 * 当搜索完成时执行此方法
18
	 */
19
	public void onFinished() {
20
	}
21
}

+ 81 - 0
ipu-bluetooth/src/com/ai/ipu/bluetooth/receiver/BondBluetoothReceiver.java

@ -0,0 +1,81 @@
1
package com.ai.ipu.bluetooth.receiver;
2

3
import java.lang.reflect.Method;
4

5
import com.ai.ipu.bluetooth.listener.OnBondStateChangedListener;
6

7
import android.bluetooth.BluetoothDevice;
8
import android.content.BroadcastReceiver;
9
import android.content.Context;
10
import android.content.Intent;
11

12
/**
13
 * 配对状态改变广播接收者
14
 * 
15
 * @author softm
16
 * 
17
 */
18
public class BondBluetoothReceiver extends BroadcastReceiver {
19
	private OnBondStateChangedListener bondListener;
20

21
	/**
22
	 * 配对状态改变广播接收者构造器
23
	 * 
24
	 * @param bondListener
25
	 *            配对状态改变事件监听器
26
	 */
27
	public BondBluetoothReceiver(OnBondStateChangedListener bondListener) {
28
		this.bondListener = bondListener;
29
	}
30

31
	@Override
32
	public void onReceive(Context context, Intent intent) {
33
		// 设备配对状态改变
34
		if(intent.getAction().equals("android.bluetooth.device.action.PAIRING_REQUEST")){
35
			BluetoothDevice device = intent
36
					.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
37
			try {
38
				if(bondListener.onPairingRequest(device)){
39
					String tmp = "123";
40
					Method setPsd;
41
					try {
42
						setPsd = device.getClass().getDeclaredMethod(
43
								"setPin", new Class[]{byte[].class});
44
						setPsd.invoke(device, new Object[] {tmp.getBytes()});
45
						Method createBondMethod = device.getClass().getMethod("createBond");  
46
				        createBondMethod.invoke(device);  
47
					} catch (Exception e) {
48
						e.printStackTrace();
49
					}
50
				}
51
			} catch (Exception e) {
52
				// TODO Auto-generated catch block
53
				e.printStackTrace();
54
			}
55
		}else if (intent.getAction().equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
56
			// 取得状态改变的设备
57
			BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
58
			// 调用状态改变事件监听器
59
			int bondState = device.getBondState();
60
			if (bondState==BluetoothDevice.BOND_BONDING) {
61
				try {
62
					bondListener.onBonding(device);
63
				} catch (Exception e) {
64
					// TODO Auto-generated catch block
65
					e.printStackTrace();
66
				}
67
			}else if(bondState==BluetoothDevice.BOND_BONDED){
68
				try {
69
					if(bondListener.onBonded(device)){
70
						// 取消状态改变广播接收者的注册
71
						context.unregisterReceiver(this);
72
					}
73
				} catch (Exception e) {
74
					// TODO Auto-generated catch block
75
					e.printStackTrace();
76
				}
77
			}
78
		}
79
	}
80

81
}

+ 57 - 0
ipu-bluetooth/src/com/ai/ipu/bluetooth/receiver/OpenBluetoothReceiver.java

@ -0,0 +1,57 @@
1
package com.ai.ipu.bluetooth.receiver;
2

3
import com.ai.ipu.bluetooth.listener.OnOpenBluetoothListener;
4

5
import android.bluetooth.BluetoothAdapter;
6
import android.content.BroadcastReceiver;
7
import android.content.Context;
8
import android.content.Intent;
9

10
/**
11
 * 蓝牙启动事件监听器,主要用于监听蓝牙从启动到准备好这一过程,以便蓝牙搜索设备的功能得到正常运行。
12
 * 
13
 * @author softm
14
 * 
15
 */
16
public class OpenBluetoothReceiver extends BroadcastReceiver {
17
	// 当打开蓝牙时,传入的监听器
18
	private OnOpenBluetoothListener openListener;
19
	private BluetoothAdapter mBluetoothAdapter;
20

21
	/**
22
	 * 打开蓝牙广播接收者构造器
23
	 * 
24
	 * @param openListener 打开蓝牙事件监听器
25
	 * @param bluetoothAdapter 蓝牙适配器
26
	 */
27
	public OpenBluetoothReceiver(OnOpenBluetoothListener openListener,
28
			BluetoothAdapter bluetoothAdapter) {
29
		this.openListener = openListener;
30
		this.mBluetoothAdapter = bluetoothAdapter;
31
	}
32

33
	@Override
34
	public void onReceive(Context context, Intent intent) {
35
		int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
36
		if(openListener!=null){
37
			switch (state) {
38
			case BluetoothAdapter.STATE_TURNING_ON:
39
				openListener.OnOpen(mBluetoothAdapter);
40
				break;
41
			case BluetoothAdapter.STATE_ON:
42
				openListener.OnOpened(mBluetoothAdapter);
43
				break;
44
			case BluetoothAdapter.STATE_TURNING_OFF:
45
				openListener.OnClose(mBluetoothAdapter);
46
				break;
47
			case BluetoothAdapter.STATE_OFF:
48
				openListener.OnClosed(mBluetoothAdapter);
49
				break;
50
			}
51
		}
52
		if(state==BluetoothAdapter.STATE_OFF){
53
			//取消注册蓝牙状态广播接收者
54
			context.unregisterReceiver(this);
55
		}
56
	}
57
}

+ 51 - 0
ipu-bluetooth/src/com/ai/ipu/bluetooth/receiver/ScanBluetoothReceiver.java

@ -0,0 +1,51 @@
1
package com.ai.ipu.bluetooth.receiver;
2

3
import com.ai.ipu.bluetooth.listener.OnSearchDeviceListener;
4
import com.ai.ipu.bluetooth.util.BluetoothTool;
5

6
import android.bluetooth.BluetoothAdapter;
7
import android.bluetooth.BluetoothDevice;
8
import android.content.BroadcastReceiver;
9
import android.content.Context;
10
import android.content.Intent;
11

12
/**
13
 * 蓝牙搜索状态广播接收者
14
 * 
15
 * @author softm
16
 * 
17
 */
18
public class ScanBluetoothReceiver extends BroadcastReceiver {
19
	private OnSearchDeviceListener searchListener;
20
	private BluetoothTool mBluetoothTool;
21

22
	/**
23
	 * 广播接收者构造器
24
	 * 
25
	 * @param mActivity 上下文对象
26
	 * @param searchListener 搜索状态监听器
27
	 */
28
	public ScanBluetoothReceiver(BluetoothTool mBluetoothAdapter,OnSearchDeviceListener searchListener) {
29
		this.searchListener = searchListener;
30
		this.mBluetoothTool = mBluetoothAdapter;
31
	}
32

33
	public void onReceive(Context context, Intent intent) {
34
		if (intent.getAction().equals(BluetoothDevice.ACTION_FOUND)) {
35
			// 获取扫描到的蓝牙设备
36
			BluetoothDevice bluetoothDevice = intent
37
					.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
38
			// 将当前搜索到的设备传入监听器
39
			if (searchListener.onFound(bluetoothDevice)) {
40
				// 停止搜索蓝牙设备
41
				mBluetoothTool.cancelDiscovery();
42
			}
43
		} else if (intent.getAction().equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
44
			// 搜索完成时调用监听器
45
			searchListener.onFinished();
46
			// 注销监听
47
			context.unregisterReceiver(this);
48
		}
49
	}
50

51
}

+ 9 - 0
ipu-bluetooth/src/com/ai/ipu/bluetooth/util/BluetoothConstant.java

@ -0,0 +1,9 @@
1
package com.ai.ipu.bluetooth.util;
2

3
public interface BluetoothConstant {
4
	public String AUTO_SEARCH_KEY = "autosearch";
5
	public int SUC_REQ_SEARCH = 991;
6
	public int ERR_REQ_SEARCH = 992;
7
	public int SUC_REQ_SEND_FILE = 981;
8
	public int ERR_REQ_SEND_FILE = 982;
9
}

+ 333 - 0
ipu-bluetooth/src/com/ai/ipu/bluetooth/util/BluetoothTool.java

@ -0,0 +1,333 @@
1
package com.ai.ipu.bluetooth.util;
2

3
import java.io.File;
4
import java.lang.reflect.Method;
5
import java.util.Set;
6

7
import android.app.Activity;
8
import android.bluetooth.BluetoothAdapter;
9
import android.bluetooth.BluetoothDevice;
10
import android.bluetooth.BluetoothSocket;
11
import android.content.ComponentName;
12
import android.content.ContentValues;
13
import android.content.Intent;
14
import android.content.IntentFilter;
15
import android.net.Uri;
16
import android.os.Handler;
17
import android.os.HandlerThread;
18

19
import com.ai.ipu.bluetooth.listener.OnBondStateChangedListener;
20
import com.ai.ipu.bluetooth.listener.OnOpenBluetoothListener;
21
import com.ai.ipu.bluetooth.listener.OnSearchDeviceListener;
22
import com.ai.ipu.bluetooth.receiver.BondBluetoothReceiver;
23
import com.ai.ipu.bluetooth.receiver.OpenBluetoothReceiver;
24
import com.ai.ipu.bluetooth.receiver.ScanBluetoothReceiver;
25
import com.wade.mobile.util.Utility;
26

27
public class BluetoothTool {
28
	// 用于保存传入的上下文
29
	private Activity mActivity;
30
	// 蓝牙适配器
31
	private BluetoothAdapter mBluetoothAdapter;
32
	// 打开蓝牙事件监听器
33
	private BluetoothSocket socket; // 蓝牙连接socket
34
	// 跨线程操作UI
35
	private Handler socketHandler = new Handler();
36
	{
37
		HandlerThread handlerThread = new HandlerThread("other_thread");
38
		handlerThread.start();
39
		socketHandler = new Handler(handlerThread.getLooper());
40
	}
41
	
42
	/**
43
	 * 工具类构造器
44
	 * @param activity 上下文对象
45
	 */
46
	public BluetoothTool(Activity activity) {
47
		this.mActivity = activity;
48
		// 取得蓝牙适配器
49
		mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
50
		if(mBluetoothAdapter==null){
51
			throw new RuntimeException("bluetooth is unavailable ");
52
		}
53
	}
54
	
55
	/**
56
	 * 蓝牙设备是否可用
57
	 * @return 是否可用
58
	 */
59
	public boolean isEnabled() {
60
		return mBluetoothAdapter.isEnabled();
61
	}
62

63
	/**
64
	 * 蓝牙设备是否可被发现
65
	 * @return 是否可被发现
66
	 */
67
	public boolean isDiscovering() {
68
		return mBluetoothAdapter.isDiscovering();
69
	}
70
	
71
	/**
72
	 * 判断设备是否繁忙
73
	 * @return 设备繁忙
74
	 */
75
	public boolean isBusy(){
76
		int state=mBluetoothAdapter.getState();
77
		return state==BluetoothAdapter.STATE_TURNING_OFF || state==BluetoothAdapter.STATE_TURNING_ON;
78
	}
79

80
	/**
81
	 * 无询问直接打开蓝牙设备
82
	 * @return 是否打开成功
83
	 */
84
	public boolean openBluetooth(OnOpenBluetoothListener openListener) {
85
		// 调用监听器中的OnOpen方法
86
		IntentFilter intentFilter = new IntentFilter();
87
		intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
88
		OpenBluetoothReceiver openReceiver = new OpenBluetoothReceiver(openListener, mBluetoothAdapter);
89
		mActivity.registerReceiver(openReceiver, intentFilter);
90
		return mBluetoothAdapter.enable();
91
	}
92
	
93
	public boolean openBluetooth(){
94
		return openBluetooth(null);
95
	}
96
	
97
	/**
98
	 * 关闭蓝牙设备。
99
	 */
100
	public void closeBluetooth() {
101
		mBluetoothAdapter.disable();
102
	}
103
	
104
	/**
105
	 * 设置蓝牙可见
106
	 * @param DiscoverableTime 蓝牙可见时间
107
	 */
108
	public void discoverable(int discoverableTime) {
109
		//发送请求,设置蓝牙可见时间
110
		Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
111
		intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,
112
				discoverableTime);
113
		mActivity.startActivity(intent);
114
	}
115
	
116
	/**
117
	 * 搜索蓝牙设备,此方法会尽可能的将查找事件完成。
118
	 * @param searchListener 远程蓝牙搜索监听器
119
	 * @param autoOpenBluetooth 自动开启蓝牙,true或false
120
	 */
121
	public void searchDevice(final OnSearchDeviceListener searchListener, boolean autoOpenBluetooth) {
122
		if (!isEnabled() && !autoOpenBluetooth) {
123
			// 蓝牙设备不可用或没有开启
124
			throw new RuntimeException("BluetoothTools:Bluetooth device is unavailable!");
125
		} else {
126
			if (!isEnabled()) {
127
				// 如果蓝牙设备没有开启,则自动开启
128
				OnOpenBluetoothListener openListener = new OnOpenBluetoothListener() {
129
					public void OnOpened(BluetoothAdapter adapter) {
130
						// 开始查找设备。
131
						search(searchListener);
132
					}
133
				};
134
				if (!openBluetooth(openListener)) {
135
					// 蓝牙设备启动失败
136
					throw new RuntimeException(
137
							"BluetoothTools:Bluetooth device open failed!");
138
				}
139
			} else {
140
				/*确保蓝牙设备是开启状态并且已经准备好,开始搜索。*/
141
				search(searchListener);
142
			}
143
		}
144
	}
145
	
146
	/**
147
	 * 开始蓝牙搜索功能
148
	 * @param searchListener 蓝牙搜索监听器
149
	 */
150
	private boolean search(OnSearchDeviceListener searchListener) {
151
		// 注册蓝牙扫描状态广播接收者
152
		IntentFilter intentFilter = new IntentFilter();
153
		intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
154
		intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
155
		ScanBluetoothReceiver mScanBluetoothReceiver = new ScanBluetoothReceiver(this, searchListener);
156
		mActivity.registerReceiver(mScanBluetoothReceiver, intentFilter);
157
		// 开启远程设备扫描
158
		return mBluetoothAdapter.startDiscovery();
159
	}
160

161
	/**
162
	 * 取消对远程蓝牙设备的搜索
163
	 */
164
	public void cancelDiscovery() {
165
		mBluetoothAdapter.cancelDiscovery();
166
	}
167
	
168
	/**
169
	 * 判断是否已与此设备配对
170
	 * @param device 待配对的设备
171
	 * @return 是否配对
172
	 */
173
	public boolean isPaired(BluetoothDevice device) {
174
		return device.getBondState() == BluetoothDevice.BOND_BONDED;
175
	}
176

177
	/**
178
	 * 获取已经配对的蓝牙设备
179
	 * @return
180
	 */
181
	public Set<BluetoothDevice> getBondedDevices() {
182
		return mBluetoothAdapter.getBondedDevices();
183
	}
184

185
	/**
186
	 * 远程蓝牙配对设备
187
	 * @param device 待配对的远程蓝牙设备
188
	 * @return 是否已经配对
189
	 * @throws Exception 
190
	 */
191
	public boolean doPair(final BluetoothDevice device, OnBondStateChangedListener bondListener) throws Exception {
192
		if (isPaired(device)) {
193
			return true; // 已经配则直接返回true
194
		} else {
195
			BondBluetoothReceiver mBondBluetoothReceiver = new BondBluetoothReceiver(bondListener);
196
			IntentFilter intentFilter = new IntentFilter();
197
			intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
198
			// 配对请求广播
199
			intentFilter.addAction("android.bluetooth.device.action.PAIRING_REQUEST");
200
			// 注册配对状态改变广播接收者
201
			mActivity.registerReceiver(mBondBluetoothReceiver, intentFilter);
202
			return false;
203
		}
204
	}
205
	
206
	/**
207
	 * 取消配对,暂无使用
208
	 * @param btClass
209
	 * @param device
210
	 * @return
211
	 * @throws Exception
212
	 */
213
	@SuppressWarnings("unused")
214
	public boolean cancelBondProcess(final BluetoothDevice device) throws Exception {
215
		Method createBondMethod = device.getClass().getMethod("cancelBondProcess");
216
		Boolean returnValue = (Boolean) createBondMethod.invoke(device);
217
		return returnValue.booleanValue();
218
	}
219

220
	/**
221
	 * 通过蓝牙发送文件
222
	 * @param file 将要发送的文件
223
	 * @param device 目标蓝牙设备
224
	 * @param bondListener 配对状态改变监听器
225
	 * @throws Exception 
226
	 */
227
	public void sendFileByAutoPair(final File file,final BluetoothDevice device, final OnBondStateChangedListener bondListener) throws Exception {
228
		OnBondStateChangedListener sysBondListener=new OnBondStateChangedListener() {
229
			public boolean onBonded(BluetoothDevice mDevice) throws Exception {
230
				bondListener.onBonded(mDevice);
231
				// 接收文件的设备与当前配对成功的设备的MAC相同
232
				if(mDevice.getAddress().equals(device.getAddress())){
233
					sendFile(file, mDevice);
234
					//取消继续监听
235
					return true;
236
				}else{
237
					return false;
238
				}
239
			}
240
			public void onBonding(BluetoothDevice device) throws Exception {
241
				bondListener.onBonding(device);
242
			}
243
			public boolean onPairingRequest(BluetoothDevice device)
244
					throws Exception {
245
				return bondListener.onPairingRequest(device);
246
			}
247
		};
248
		
249
		BondBluetoothReceiver mBondBluetoothReceiver = new BondBluetoothReceiver(sysBondListener);
250
		// 注册设备配对状态改变监听器
251
		IntentFilter intentFilter = new IntentFilter();
252
		intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
253
		// 配对请求广播
254
		intentFilter.addAction("android.bluetooth.device.action.PAIRING_REQUEST");
255
		// 注册配对状态改变广播接收者
256
		mActivity.registerReceiver(mBondBluetoothReceiver, intentFilter);
257
		
258
		if(device.getBondState()==BluetoothDevice.BOND_BONDED){
259
			sendFile(file, device);//如果已配对则发送文件
260
		}else{
261
			initSocketByThread(device);//没有配置则先进行配对
262
		}
263
	}
264
	
265
	/**
266
	 * 取得BluetoothSocket
267
	 * @throws Exception 
268
	 */
269
	private void initSocket(BluetoothDevice device) throws Exception {
270
		/*官方代码无法执行*/
271
		// mTouchObject.bluetoothDevice.createRfcommSocketToServiceRecord(UUID.fromString(CONNECT_UUID));
272
		/*反射获取socket*/
273
		Method m = device.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
274
		socket = (BluetoothSocket) m.invoke(device, 1);
275
	}
276
	
277
	private void initSocketByThread(final BluetoothDevice device){
278
		socketHandler.post(new Runnable() {
279
			public void run() {
280
				try{
281
					initSocket(device); // 取得socket
282
					socket.connect(); // socket连接
283
				}catch(Exception e){
284
					e.printStackTrace();
285
				}
286
			}
287
		});
288
	}
289

290
	/**
291
	 * 通过蓝牙发送文件
292
	 * @param file 将要发送的文件
293
	 * @param device 目标蓝牙设备
294
	 * @throws Exception 
295
	 */
296
	public void sendFile(final File file, final BluetoothDevice device) throws Exception {
297
		if (file.exists()) {
298
			// 调用系统程序发送文件
299
			Uri uri = Uri.fromFile(file);
300
			
301
			ContentValues cv = new ContentValues();
302
			cv.put("uri", uri.toString());
303
			cv.put("destination", device.getAddress());
304
			cv.put("direction", 0);
305
			cv.put("timestamp", System.currentTimeMillis());
306
			mActivity.getContentResolver().insert(
307
					Uri.parse("content://com.android.bluetooth.opp/btopp"),
308
					cv);
309
		} else {
310
			Utility.error("The file "+file.getName()+" does not exist.");
311
		}
312
	}
313
	
314
	/**
315
	 * 支持android4.1以上的蓝牙文件传输
316
	 * @param file
317
	 * @param device
318
	 * @throws Exception
319
	 */
320
	public void sendFile(final File file) throws Exception {
321
		if (file.exists()) {
322
			// 调用系统程序发送文件
323
			Uri uri = Uri.fromFile(file);
324
			Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
325
			sharingIntent.setType("image/jpeg");
326
			sharingIntent.setComponent(new ComponentName("com.android.bluetooth", "com.android.bluetooth.opp.BluetoothOppLauncherActivity"));
327
			sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
328
			mActivity.startActivity(sharingIntent);
329
		} else {
330
			Utility.error("The file "+file.getName()+" does not exist.");
331
		}
332
	}
333
}