Selaa lähdekoodia

邮件发送功能依赖包

1712772270@qq.com 8 vuotta sitten
vanhempi
commit
88134691d6

+ 34 - 0
ipu-mail/AndroidManifest.xml

@ -0,0 +1,34 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
    package="com.ai.ipu.mail"
4
    android:versionCode="1"
5
    android:versionName="1.0" >
6
7
    <uses-sdk
8
        android:minSdkVersion="8"
9
        android:targetSdkVersion="15" />
10
    
11
   <uses-permission android:name="android.permission.INTERNET"/>
12
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
13
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
14
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
15
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
16
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
17
    
18
    <application 
19
        android:allowBackup="true"
20
        android:icon="@drawable/ic_launcher"
21
        android:label="@string/app_name"
22
        android:theme="@style/AppTheme">
23
        <activity 
24
            android:name=".MainActivity">
25
            <intent-filter>
26
                <action android:name="android.intent.action.MAIN" />
27
                <category android:name="android.intent.category.LAUNCHER" />
28
            </intent-filter>
29
        </activity>
30
        
31
    </application>
32
    
33
  
34
</manifest>

BIN
ipu-mail/assets/video.mp4


+ 6 - 0
ipu-mail/gen/com/ai/ipu/mail/BuildConfig.java

@ -0,0 +1,6 @@
1
/** Automatically generated file. DO NOT MODIFY */
2
package com.ai.ipu.mail;
3
4
public final class BuildConfig {
5
    public final static boolean DEBUG = true;
6
}

+ 75 - 0
ipu-mail/gen/com/ai/ipu/mail/R.java

@ -0,0 +1,75 @@
1
/* AUTO-GENERATED FILE.  DO NOT MODIFY.
2
 *
3
 * This class was automatically generated by the
4
 * aapt tool from the resource data it found.  It
5
 * should not be modified by hand.
6
 */
7
8
package com.ai.ipu.mail;
9
10
public final class R {
11
    public static final class attr {
12
    }
13
    public static final class dimen {
14
        /**  Default screen margins, per the Android Design guidelines. 
15
16
         Example customization of dimensions originally defined in res/values/dimens.xml
17
         (such as screen margins) for screens with more than 820dp of available width. This
18
         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively).
19
    
20
         */
21
        public static final int activity_horizontal_margin=0x7f040000;
22
        public static final int activity_vertical_margin=0x7f040001;
23
    }
24
    public static final class drawable {
25
        public static final int ic_launcher=0x7f020000;
26
    }
27
    public static final class id {
28
        public static final int btn_cancel=0x7f070008;
29
        public static final int btn_mail_file=0x7f070000;
30
        public static final int btn_ok=0x7f070007;
31
        public static final int btn_selectImg=0x7f070002;
32
        public static final int et_imgpath=0x7f070003;
33
        public static final int et_password=0x7f070006;
34
        public static final int et_receiver=0x7f070001;
35
        public static final int et_username=0x7f070005;
36
        public static final int textView1=0x7f070004;
37
    }
38
    public static final class layout {
39
        public static final int activity_share=0x7f030000;
40
        public static final int dialog_set_userpwd=0x7f030001;
41
    }
42
    public static final class string {
43
        public static final int action_settings=0x7f050002;
44
        public static final int app_name=0x7f050000;
45
        public static final int hello_world=0x7f050001;
46
    }
47
    public static final class style {
48
        /** 
49
        Base application theme, dependent on API level. This theme is replaced
50
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
51
    
52
53
            Theme customizations available in newer API levels can go in
54
            res/values-vXX/styles.xml, while customizations related to
55
            backward-compatibility can go here.
56
        
57
58
        Base application theme for API 11+. This theme completely replaces
59
        AppBaseTheme from res/values/styles.xml on API 11+ devices.
60
    
61
 API 11 theme customizations can go here. 
62
63
        Base application theme for API 14+. This theme completely replaces
64
        AppBaseTheme from BOTH res/values/styles.xml and
65
        res/values-v11/styles.xml on API 14+ devices.
66
    
67
 API 14 theme customizations can go here. 
68
         */
69
        public static final int AppBaseTheme=0x7f060000;
70
        /**  Application theme. 
71
 All customizations that are NOT specific to a particular API-level can go here. 
72
         */
73
        public static final int AppTheme=0x7f060001;
74
    }
75
}

BIN
ipu-mail/libs/activation.jar


BIN
ipu-mail/libs/additionnal.jar


BIN
ipu-mail/libs/mail.jar


+ 3 - 0
ipu-mail/lint.xml

@ -0,0 +1,3 @@
1
<?xml version="1.0" encoding="UTF-8"?>
2
<lint>
3
</lint>

+ 20 - 0
ipu-mail/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
#}

+ 15 - 0
ipu-mail/project.properties

@ -0,0 +1,15 @@
1
# This file is automatically generated by Android Tools.
2
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3
#
4
# This file must be checked in Version Control Systems.
5
#
6
# To customize properties used by the Ant build system edit
7
# "ant.properties", and override values to adapt the script to your
8
# project structure.
9
#
10
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12
13
# Project target.
14
target=android-22
15
android.library=false

BIN
ipu-mail/res/drawable-mdpi/ic_launcher.png


+ 35 - 0
ipu-mail/res/layout/activity_share.xml

@ -0,0 +1,35 @@
1
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2
    xmlns:tools="http://schemas.android.com/tools"
3
    android:layout_width="match_parent"
4
    android:layout_height="match_parent"
5
    android:orientation="vertical"
6
    tools:context="com.ai.ipu.mail.MainActivity" >
7
8
    <Button
9
        android:id="@+id/btn_mail_file"
10
        android:layout_width="wrap_content"
11
        android:layout_height="wrap_content"
12
        android:text="email_file" />
13
14
    <EditText
15
        android:id="@+id/et_receiver"
16
        android:layout_width="wrap_content"
17
        android:layout_height="wrap_content"
18
        android:hint="请输入收件者邮箱"
19
         />
20
    
21
     <Button
22
        android:id="@+id/btn_selectImg"
23
        android:layout_width="wrap_content"
24
        android:layout_height="wrap_content"
25
        android:layout_weight="0"
26
        android:text="选择图片"
27
        android:layout_gravity="center"></Button>
28
      <EditText
29
        android:id="@+id/et_imgpath"
30
        android:layout_width="wrap_content"
31
        android:layout_height="wrap_content"
32
        android:hint="请输入收件者邮箱"
33
         />
34
35
</LinearLayout>

+ 54 - 0
ipu-mail/res/layout/dialog_set_userpwd.xml

@ -0,0 +1,54 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
    android:layout_width="200dp"
4
    android:layout_height="match_parent"
5
    android:background="#fff"
6
    android:orientation="vertical" >
7
8
    <TextView
9
        android:id="@+id/textView1"
10
        android:layout_width="match_parent"
11
        android:layout_height="wrap_content"
12
        android:background="#66ff6600"
13
        android:gravity="center"
14
        android:padding="10dp"
15
        android:text="设置账号密码"
16
        android:textSize="20sp" />
17
    
18
    <EditText
19
        android:id="@+id/et_username"
20
        android:layout_width="match_parent"
21
        android:layout_height="wrap_content"
22
        android:hint="请输入邮箱账号"
23
       >
24
    </EditText>
25
26
    <EditText
27
        android:id="@+id/et_password"
28
        android:layout_width="match_parent"
29
        android:layout_height="wrap_content"
30
        android:hint="请输入密码密码"
31
        android:inputType="textPassword" >
32
    </EditText>
33
34
35
    <LinearLayout
36
        android:layout_width="match_parent"
37
        android:layout_height="wrap_content" >
38
39
        <Button
40
            android:id="@+id/btn_ok"
41
            android:layout_width="0dp"
42
            android:layout_height="wrap_content"
43
            android:layout_weight="1"
44
            android:text="确定" />
45
46
        <Button
47
            android:id="@+id/btn_cancel"
48
            android:layout_width="0dp"
49
            android:layout_height="wrap_content"
50
            android:layout_weight="1"
51
            android:text="取消" />
52
    </LinearLayout>
53
54
</LinearLayout>

+ 11 - 0
ipu-mail/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:style/Theme.Light.NoTitleBar">
8
        <!-- API 11 theme customizations can go here. -->
9
    </style>
10
11
</resources>

+ 12 - 0
ipu-mail/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:style/Theme.Light.NoTitleBar">
9
        <!-- API 14 theme customizations can go here. -->
10
    </style>
11
12
</resources>

+ 10 - 0
ipu-mail/res/values-w820dp/dimens.xml

@ -0,0 +1,10 @@
1
<resources>
2
3
    <!--
4
         Example customization of dimensions originally defined in res/values/dimens.xml
5
         (such as screen margins) for screens with more than 820dp of available width. This
6
         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively).
7
    -->
8
    <dimen name="activity_horizontal_margin">64dp</dimen>
9
10
</resources>

+ 7 - 0
ipu-mail/res/values/dimens.xml

@ -0,0 +1,7 @@
1
<resources>
2
3
    <!-- Default screen margins, per the Android Design guidelines. -->
4
    <dimen name="activity_horizontal_margin">16dp</dimen>
5
    <dimen name="activity_vertical_margin">16dp</dimen>
6
7
</resources>

+ 8 - 0
ipu-mail/res/values/strings.xml

@ -0,0 +1,8 @@
1
<?xml version="1.0" encoding="utf-8"?>
2
<resources>
3
4
    <string name="app_name">ipu-mail</string>
5
    <string name="hello_world">Hello world!</string>
6
    <string name="action_settings">Settings</string>
7
8
</resources>

+ 20 - 0
ipu-mail/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:style/Theme.Light.NoTitleBar">
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>

+ 193 - 0
ipu-mail/src/com/ai/ipu/mail/MainActivity.java

@ -0,0 +1,193 @@
1
package com.ai.ipu.mail;
2
3
import java.io.File;
4
import java.io.InputStream;
5
6
import javax.mail.event.TransportEvent;
7
8
import com.ai.ipu.mail.R;
9
import com.ai.ipu.mail.func.MailSender;
10
import com.ai.ipu.mail.func.MyTransportStateListenerImp;
11
import com.ai.ipu.mail.func.SenderRunnable;
12
import com.ai.ipu.mail.func.MailSender.OnTransportStateListener;
13
import com.ai.ipu.mail.util.LoadPictureUtils;
14
import com.ai.ipu.mail.util.ShareUtil;
15
import com.ai.ipu.mobile.app.ApplicationManager;
16
import com.ai.ipu.mobile.res.assets.AssetsUtil;
17
import android.annotation.SuppressLint;
18
import android.app.Activity;
19
import android.app.AlertDialog;
20
import android.content.Intent;
21
import android.content.SharedPreferences;
22
import android.content.res.AssetManager;
23
import android.graphics.BitmapFactory;
24
import android.net.Uri;
25
import android.os.Bundle;
26
import android.os.Environment;
27
import android.text.TextUtils;
28
import android.view.View;
29
import android.view.View.OnClickListener;
30
import android.widget.Button;
31
import android.widget.EditText;
32
import android.widget.Toast;
33
34
public class MainActivity extends Activity implements OnClickListener{
35
	private ShareUtil shareUtil;
36
	String filePath;
37
	private Button btnMailFile;
38
39
	private static final int SELECT_PIC_KITAAT = 1;
40
	private static final int SELECT_PIC = 0;
41
42
	private SharedPreferences mPref;
43
	private EditText etReceiver;
44
	private Button btnSelectImg;
45
	private EditText etImgpath;
46
	private MyTransportStateListenerImp listener;
47
48
	@Override
49
	protected void onCreate(Bundle savedInstanceState) {
50
		super.onCreate(savedInstanceState);
51
		ApplicationManager.initApplication(getApplication());
52
		setContentView(R.layout.activity_share);
53
		listener = new MyTransportStateListenerImp(this);
54
		shareUtil = new ShareUtil(this);
55
56
		mPref = getSharedPreferences("config", MODE_PRIVATE);
57
		btnSelectImg = (Button) findViewById(R.id.btn_selectImg);
58
		
59
		etImgpath = (EditText) findViewById(R.id.et_imgpath);
60
61
		btnMailFile = (Button) this.findViewById(R.id.btn_mail_file);
62
		etReceiver = (EditText) this.findViewById(R.id.et_receiver);
63
64
		etReceiver.setText(mPref.getString("mailreceiver", null));
65
66
		btnMailFile.setOnClickListener(this);
67
		btnSelectImg.setOnClickListener(this);
68
69
	}
70
	
71
	
72
	
73
	@Override
74
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
75
		super.onActivityResult(requestCode, resultCode, data);
76
		switch (requestCode) {
77
		case SELECT_PIC_KITAAT:
78
			Uri uri = data.getData();
79
			String path = LoadPictureUtils.getPath(this, uri);
80
			etImgpath.setText(path);
81
//			ivSelectedImg.setImageBitmap(BitmapFactory.decodeFile(path));
82
			break;
83
84
		case SELECT_PIC:
85
			String path2 = LoadPictureUtils.selectImage(this, data);
86
			break;
87
		}
88
	}
89
90
	/**
91
	 * 提示输入邮件收件者
92
	 */
93
	private void showPasswordDialog() {
94
		String username = mPref.getString("username", null);
95
		String receiverString = etReceiver.getText().toString();
96
		if (!TextUtils.isEmpty(username)) {
97
			if (!TextUtils.isEmpty(receiverString)) {
98
				// 记录最近一次发送过的邮箱账号到sp中
99
				mPref.edit().putString("mailreceiver", receiverString).commit();
100
101
				// 已经保存过用户名和密码,直接发送
102
				String password = mPref.getString("password", null);
103
104
				Toast.makeText(this, "邮件正在发送,请稍后..." + receiverString,
105
						Toast.LENGTH_SHORT).show();
106
				shareUtil.shareImageBymail(username, password, listener,
107
						"this is the test subject", "this is the test body",
108
						receiverString,
109
//						Environment.getExternalStorageDirectory() + "/img.jpg");
110
						etImgpath.getText().toString());
111
			} else {
112
				Toast.makeText(MainActivity.this, "输入收件者邮箱", Toast.LENGTH_SHORT)
113
						.show();
114
			}
115
		} else {
116
			// 录入邮件发送者信息
117
			showSenderConfigDialog();
118
		}
119
	}
120
121
	/**
122
	 * 显示邮件发送者录入框
123
	 */
124
	private void showSenderConfigDialog() {
125
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
126
		final AlertDialog dialog = builder.create();
127
		View view = shareUtil.initDialogView(R.layout.dialog_set_userpwd, true);
128
		dialog.setView(view, 0, 0, 0, 0);// 设置边距为0,保证在2.x的版本上运行没问题
129
130
		final EditText etUsername = (EditText) view
131
				.findViewById(R.id.et_username);
132
		final EditText etPassword = (EditText) view
133
				.findViewById(R.id.et_password);
134
		Button btnOK = (Button) view.findViewById(R.id.btn_ok);
135
		Button btnCancel = (Button) view.findViewById(R.id.btn_cancel);
136
137
		btnOK.setOnClickListener(new OnClickListener() {
138
			@SuppressLint("NewApi")
139
			@Override
140
			public void onClick(View v) {
141
				String username = etUsername.getText().toString();
142
				String password = etPassword.getText().toString();
143
				if (!username.isEmpty() && !password.isEmpty()) {
144
					// 保存用户名和密码
145
					mPref.edit().putString("username", username).commit();
146
					mPref.edit().putString("password", password).commit();
147
					dialog.dismiss();
148
				} else {
149
					Toast.makeText(MainActivity.this, "输入框内容不能为空!",
150
							Toast.LENGTH_SHORT).show();
151
				}
152
			}
153
		});
154
155
		btnCancel.setOnClickListener(new OnClickListener() {
156
			@Override
157
			public void onClick(View v) {
158
				dialog.dismiss();// 隐藏dialog
159
			}
160
		});
161
162
		dialog.show();
163
164
	}
165
	private void copyAssets() {
166
167
	}
168
	@Override
169
	public void onClick(View v) {
170
		switch (v.getId()) {
171
		case R.id.btn_mail_file://点击发送按钮
172
			// 弹出对话框输入邮箱用户名和密码
173
			showPasswordDialog();
174
			break;
175
176
		case R.id.btn_selectImg://点击选择图片
177
			Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
178
179
			intent.addCategory(Intent.CATEGORY_OPENABLE);
180
181
			intent.setType("image/jpeg");
182
183
			if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
184
				startActivityForResult(intent, SELECT_PIC_KITAAT);
185
			} else {
186
				startActivityForResult(intent, SELECT_PIC);
187
			}
188
			break;
189
		}
190
		
191
	}
192
	
193
}

+ 29 - 0
ipu-mail/src/com/ai/ipu/mail/func/JSSEProvider.java

@ -0,0 +1,29 @@
1
package com.ai.ipu.mail.func;
2
3
import java.security.AccessController;
4
import java.security.Provider;
5
6
/**
7
 * 加密
8
 * @author Kelly
9
 *
10
 */
11
public class JSSEProvider extends Provider {
12
13
	protected JSSEProvider() {
14
		 super("HarmonyJSSE", 1.0, "Harmony JSSE Provider");
15
		 AccessController.doPrivileged(new java.security.PrivilegedAction<Void>() {
16
	            public Void run() {
17
	                put("SSLContext.TLS",
18
	                        "org.apache.harmony.xnet.provider.jsse.SSLContextImpl");
19
	                put("Alg.Alias.SSLContext.TLSv1", "TLS");
20
	                put("KeyManagerFactory.X509",
21
	                        "org.apache.harmony.xnet.provider.jsse.KeyManagerFactoryImpl");
22
	                put("TrustManagerFactory.X509",
23
	                        "org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl");
24
	                return null;
25
	            }
26
	        });
27
	}
28
29
}

+ 40 - 0
ipu-mail/src/com/ai/ipu/mail/func/MailSendByApp.java

@ -0,0 +1,40 @@
1
package com.ai.ipu.mail.func;
2
3
import org.json.JSONArray;
4
import org.json.JSONException;
5
import org.json.JSONObject;
6
7
import android.content.SharedPreferences;
8
import android.widget.TabHost.OnTabChangeListener;
9
10
import com.ai.ipu.mail.func.MailSender.OnTransportStateListener;
11
import com.ai.ipu.mail.util.ShareUtil;
12
import com.wade.mobile.frame.IWadeMobile;
13
import com.wade.mobile.frame.plugin.Plugin;
14
15
public class MailSendByApp extends Plugin {
16
	private ShareUtil shareUtil;
17
	private MyTransportStateListenerImp listener;
18
	
19
	public MailSendByApp(IWadeMobile wademobile) {
20
		super(wademobile);
21
		listener = new MyTransportStateListenerImp(context);
22
		shareUtil = new ShareUtil(context);
23
	}
24
	/**
25
	 * 发送图片到163邮箱
26
	 * @throws Exception 
27
	 */
28
	public void shareImageBymail(JSONArray params) throws Exception {
29
		String map = params.getJSONObject(0).getString("map");
30
		JSONObject obj = new JSONObject(map);
31
		String user = obj.getString("user");
32
		String password = obj.getString("password");
33
		String subject = obj.getString("subject");
34
		String body = obj.getString("body");
35
		String receiver = obj.getString("receiver");
36
		String attachment = obj.getString("attachment");
37
		System.out.println("user= " + user + "password =" + password + "subject=" + subject + "receiver=" + receiver + "attachment=" + attachment);
38
		shareUtil.shareImageBymail(user, password, listener, subject, body, receiver, attachment);
39
	}	
40
}

+ 244 - 0
ipu-mail/src/com/ai/ipu/mail/func/MailSender.java

@ -0,0 +1,244 @@
1
package com.ai.ipu.mail.func;
2
3
import java.io.ByteArrayInputStream;
4
import java.io.IOException;
5
import java.io.InputStream;
6
import java.io.OutputStream;
7
import java.io.PrintWriter;
8
import java.security.Security;
9
import java.sql.Connection;
10
import java.sql.SQLException;
11
import java.util.Properties;
12
13
import javax.activation.DataHandler;
14
import javax.activation.DataSource;
15
import javax.activation.FileDataSource;
16
import javax.mail.Authenticator;
17
import javax.mail.BodyPart;
18
import javax.mail.Message;
19
import javax.mail.MessagingException;
20
import javax.mail.Multipart;
21
import javax.mail.PasswordAuthentication;
22
import javax.mail.Session;
23
import javax.mail.Transport;
24
import javax.mail.event.TransportEvent;
25
import javax.mail.event.TransportListener;
26
import javax.mail.internet.InternetAddress;
27
import javax.mail.internet.MimeBodyPart;
28
import javax.mail.internet.MimeMessage;
29
import javax.mail.internet.MimeMultipart;
30
31
/**
32
 * 邮件发送
33
 * 
34
 * @author Kelly
35
 * 
36
 */
37
public class MailSender extends Authenticator {
38
39
	private String user;
40
41
	private String password;
42
43
	private Session session;
44
45
	private String mailhost = "smtp.gmail.com";// 默认用gmail发送
46
47
	private Multipart messageMultipart;
48
49
	private Properties properties;
50
51
	private OnTransportStateListener listener;
52
53
	static {
54
		Security.addProvider(new JSSEProvider());
55
	}
56
57
	/**
58
	 * 设置参数
59
	 * 
60
	 * @param user
61
	 * @param password
62
	 */
63
	public MailSender(String user, String password) {
64
		this.user = user;
65
		this.password = password;
66
		properties = new Properties();
67
		properties.setProperty("mail.transport.protocol", "smtp");
68
		properties.setProperty("mail.host", mailhost);
69
		properties.put("mail.smtp.auth", "true");
70
		properties.put("mail.smtp.port", "465");
71
		properties.put("mail.smtp.socketFactory.port", "465");
72
		properties.put("mail.smtp.socketFactory.class",
73
				"javax.net.ssl.SSLSocketFactory");
74
		properties.put("mail.smtp.socketFactory.fallback", "false");
75
		properties.setProperty("mail.smtp.quitwait", "false");
76
77
		session = Session.getDefaultInstance(properties, this);// 创建一个新的Session实例,它不会在JVM中被作为默认实例共享
78
79
		messageMultipart = new MimeMultipart();
80
81
	}
82
83
	protected PasswordAuthentication getPasswordAuthentication() {
84
		return new PasswordAuthentication(user, password);
85
	}
86
87
	public synchronized void sendMail(String subject, String body,
88
			String sender, String recipients, String attachment)
89
			throws Exception {
90
		MimeMessage message = new MimeMessage(session);
91
		message.setSender(new InternetAddress(sender));// 邮件发送人
92
		message.setSubject(subject);// 邮件主题
93
94
		// 设置邮件内容
95
		BodyPart bodyPart = new MimeBodyPart();
96
		bodyPart.setText(body);
97
		messageMultipart.addBodyPart(bodyPart);
98
99
		// 设置邮件附件
100
		if (attachment != null) {
101
			DataSource dataSource = new FileDataSource(attachment);
102
			DataHandler dataHandler = new DataHandler(dataSource);
103
			bodyPart.setDataHandler(dataHandler);
104
			bodyPart.setFileName(attachment.substring(attachment
105
					.lastIndexOf("/") + 1));
106
		}
107
108
		message.setContent(messageMultipart);
109
110
		if (recipients.indexOf(',') > 0) {
111
			// 多个联系人
112
			message.setRecipients(Message.RecipientType.TO,
113
					InternetAddress.parse(recipients));
114
		} else {
115
			// 单个联系人
116
			message.setRecipient(Message.RecipientType.TO, new InternetAddress(
117
					recipients));
118
		}
119
		Transport transport = session.getTransport("smtp");
120
121
		// 给邮件发送状态添加监听
122
		transport.addTransportListener(new TransportListener() {
123
			@Override
124
			public void messagePartiallyDelivered(TransportEvent arg0) {
125
				// 邮件部分发送成功
126
				if (listener != null) {
127
					listener.transportPartiallyDelivered();
128
				}
129
			}
130
131
			@Override
132
			public void messageNotDelivered(TransportEvent arg0) {
133
				// 邮件发送失败
134
				if (listener != null) {
135
					listener.transportNotDelivered();
136
				}
137
			}
138
139
			@Override
140
			public void messageDelivered(TransportEvent arg0) {
141
				// 邮件发送成功
142
				if (listener != null) {
143
					listener.transportDelivered();
144
				}
145
			}
146
		});
147
148
		transport.connect();
149
		transport.sendMessage(message, message.getAllRecipients());
150
	}
151
152
	public void setOnTransportStateListener(OnTransportStateListener listener) {
153
		this.listener = listener;
154
	}
155
156
	public interface OnTransportStateListener {
157
		boolean transportBefore();// 邮件发送前
158
		void transportDelivered();// 邮件发送成功
159
		void transportPartiallyDelivered();// 邮件部分发送
160
		void transportNotDelivered();// 邮件发送失败
161
	}
162
163
	// 继承DataSource设置字符编码
164
	public class ByteArrayDataSource implements DataSource {
165
		private byte[] data;
166
		private String type;
167
168
		public ByteArrayDataSource(byte[] data, String type) {
169
			super();
170
			this.data = data;
171
			this.type = type;
172
		}
173
174
		public ByteArrayDataSource(byte[] data) {
175
			super();
176
			this.data = data;
177
		}
178
179
		public void setType(String type) {
180
			this.type = type;
181
		}
182
183
		public String getContentType() {
184
			if (type == null)
185
				return "application/octet-stream";
186
			else
187
				return type;
188
		}
189
190
		public InputStream getInputStream() throws IOException {
191
			return new ByteArrayInputStream(data);
192
		}
193
194
		public String getName() {
195
			return "ByteArrayDataSource";
196
		}
197
198
		public OutputStream getOutputStream() throws IOException {
199
			throw new IOException("Not Supported");
200
		}
201
202
		public PrintWriter getLogWriter() throws SQLException {
203
			return null;
204
		}
205
206
		public int getLoginTimeout() throws SQLException {
207
			return 0;
208
		}
209
210
		public void setLogWriter(PrintWriter out) throws SQLException {
211
212
		}
213
214
		public void setLoginTimeout(int seconds) throws SQLException {
215
216
		}
217
218
		public boolean isWrapperFor(Class<?> arg0) throws SQLException {
219
			return false;
220
		}
221
222
		public <T> T unwrap(Class<T> arg0) throws SQLException {
223
			return null;
224
		}
225
226
		public Connection getConnection() throws SQLException {
227
			return null;
228
		}
229
230
		public Connection getConnection(String theUsername, String thePassword)
231
				throws SQLException {
232
			return null;
233
		}
234
	}
235
236
	public String getMailhost() {
237
		return mailhost;
238
	}
239
240
	public void setMailhost(String mailhost) {
241
		this.mailhost = mailhost;
242
		properties.setProperty("mail.host", this.mailhost);
243
	}
244
}

+ 67 - 0
ipu-mail/src/com/ai/ipu/mail/func/MyTransportStateListenerImp.java

@ -0,0 +1,67 @@
1
package com.ai.ipu.mail.func;
2
3
import android.app.Activity;
4
import android.content.Context;
5
import android.content.SharedPreferences;
6
import android.widget.Toast;
7
8
import com.ai.ipu.mail.func.MailSender.OnTransportStateListener;
9
10
/**
11
 * 邮件发送成功与否的回掉
12
 * @author Kelly
13
 *
14
 */
15
public class MyTransportStateListenerImp implements OnTransportStateListener{
16
		private Context mContext;
17
		private SharedPreferences mPref;
18
		private String mReceiver;
19
		public MyTransportStateListenerImp(Context context){
20
			this.mContext = context;
21
			if(this.mContext != null){
22
				mPref = this.mContext.getSharedPreferences("config", Context.MODE_PRIVATE);
23
			}
24
		}
25
		// 发送之前
26
		@Override
27
		public boolean transportBefore() {			
28
			return false;
29
		}
30
31
		// 发送成功
32
		@Override
33
		public void transportDelivered() {
34
			((Activity) mContext).runOnUiThread(new Runnable() {
35
				@Override
36
				public void run() {
37
					Toast.makeText(mContext, "发送成功", Toast.LENGTH_SHORT)
38
							.show();
39
					if(mReceiver != null){
40
						mPref.edit().putString("mailreceiver", mReceiver);//记录receiver到本地
41
					}
42
				}
43
			});
44
		}
45
46
		// 部分发送成功
47
		@Override
48
		public void transportPartiallyDelivered() {
49
			
50
		}	
51
52
		// 发送失败
53
		@Override
54
		public void transportNotDelivered() {
55
			((Activity) mContext).runOnUiThread(new Runnable() {
56
				@Override
57
				public void run() {
58
					Toast.makeText(mContext, "发送失败", Toast.LENGTH_SHORT)
59
							.show();
60
				
61
				}
62
			});
63
		}
64
		public void setReceiver(String receiver){
65
			 this.mReceiver = receiver;
66
		}
67
}

+ 49 - 0
ipu-mail/src/com/ai/ipu/mail/func/SenderRunnable.java

@ -0,0 +1,49 @@
1
package com.ai.ipu.mail.func;
2
3
import com.ai.ipu.mail.func.MailSender.OnTransportStateListener;
4
5
import android.util.Log;
6
7
/**
8
 * 邮件发送线程
9
 * @author Kelly
10
 *
11
 */
12
public class SenderRunnable implements Runnable {
13
	private String user;
14
	private String password;
15
	private String subject;
16
	private String body;
17
	private String receiver;
18
	private MailSender sender;
19
	private String attachment;
20
 
21
	public SenderRunnable(String user, String password, OnTransportStateListener listener) {
22
		this.user = user;
23
		this.password = password;
24
		sender = new MailSender(user, password);
25
		sender.setOnTransportStateListener(listener);
26
		String mailhost=user.substring(user.lastIndexOf("@")+1, user.lastIndexOf("."));
27
		if(!mailhost.equals("gmail")){
28
			mailhost="smtp."+mailhost+".com";
29
			Log.i("hello", mailhost);
30
			sender.setMailhost(mailhost);
31
		}
32
	}
33
34
	public void setMail(String subject, String body, String receiver,String attachment) {
35
		this.subject = subject;
36
		this.body = body;
37
		this.receiver = receiver;
38
		this.attachment=attachment;
39
	}
40
41
	public void run() {
42
		try {
43
			sender.sendMail(subject, body, user, receiver,attachment);
44
		} catch (Exception e) {
45
			e.printStackTrace();
46
		}
47
	}
48
49
}

+ 192 - 0
ipu-mail/src/com/ai/ipu/mail/util/LoadPictureUtils.java

@ -0,0 +1,192 @@
1
package com.ai.ipu.mail.util;
2
3
import android.annotation.SuppressLint;
4
import android.annotation.TargetApi;
5
import android.content.ContentUris;
6
import android.content.Context;
7
import android.content.Intent;
8
import android.database.Cursor;
9
import android.net.Uri;
10
import android.os.Build;
11
import android.os.Environment;
12
import android.provider.DocumentsContract;
13
import android.provider.MediaStore;
14
import android.util.Log;
15
16
public class LoadPictureUtils {
17
	private Context mContext;
18
	public LoadPictureUtils(Context context){
19
		this.mContext = context;
20
	}
21
	/**
22
	 * 获取图片的本地路径
23
	 * @param context
24
	 * @param uri
25
	 * @return
26
	 */
27
	@TargetApi(Build.VERSION_CODES.KITKAT)
28
	@SuppressLint("NewApi")
29
	public static String getPath(final Context context, final Uri uri) {
30
31
		final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
32
33
		if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
34
			// ExternalStorageProvider
35
			if (isExternalStorageDocument(uri)) {
36
				final String docId = DocumentsContract.getDocumentId(uri);
37
				final String[] split = docId.split(":");
38
				final String type = split[0];
39
40
				if ("primary".equalsIgnoreCase(type)) {
41
					return Environment.getExternalStorageDirectory() + "/"
42
							+ split[1];
43
				}
44
45
			}
46
			
47
			// DownloadsProvider
48
			else if (isDownloadsDocument(uri)) {
49
				final String id = DocumentsContract.getDocumentId(uri);
50
				final Uri contentUri = ContentUris.withAppendedId(
51
						Uri.parse("content://downloads/public_downloads"),
52
						Long.valueOf(id));
53
54
				return getDataColumn(context, contentUri, null, null);
55
			}
56
			// MediaProvider
57
			else if (isMediaDocument(uri)) {
58
				final String docId = DocumentsContract.getDocumentId(uri);
59
				final String[] split = docId.split(":");
60
				final String type = split[0];
61
62
				Uri contentUri = null;
63
				if ("image".equals(type)) {
64
					contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
65
				} else if ("video".equals(type)) {
66
					contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
67
				} else if ("audio".equals(type)) {
68
					contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
69
				}
70
71
				final String selection = "_id=?";
72
				final String[] selectionArgs = new String[] { split[1] };
73
74
				return getDataColumn(context, contentUri, selection,
75
						selectionArgs);
76
			}
77
		}
78
		// MediaStore (and general)
79
		else if ("content".equalsIgnoreCase(uri.getScheme())) {
80
81
			// Return the remote address
82
			if (isGooglePhotosUri(uri))
83
				return uri.getLastPathSegment();
84
85
			return getDataColumn(context, uri, null, null);
86
		}
87
		// File
88
		else if ("file".equalsIgnoreCase(uri.getScheme())) {
89
			return uri.getPath();
90
		}
91
92
		return null;
93
	}
94
95
	/**
96
	 * Get the value of the data column for this Uri. This is useful for
97
	 * MediaStore Uris, and other file-based ContentProviders.
98
	 * 
99
	 * @param context
100
	 *            The context.
101
	 * @param uri
102
	 *            The Uri to query.
103
	 * @param selection
104
	 *            (Optional) Filter used in the query.
105
	 * @param selectionArgs
106
	 *            (Optional) Selection arguments used in the query.
107
	 * @return The value of the _data column, which is typically a file path.
108
	 */
109
	public static String getDataColumn(Context context, Uri uri,
110
			String selection, String[] selectionArgs) {
111
112
		Cursor cursor = null;
113
		final String column = "_data";
114
		final String[] projection = { column };
115
116
		try {
117
			cursor = context.getContentResolver().query(uri, projection,
118
					selection, selectionArgs, null);
119
			if (cursor != null && cursor.moveToFirst()) {
120
				final int index = cursor.getColumnIndexOrThrow(column);
121
				return cursor.getString(index);
122
			}
123
		} finally {
124
			if (cursor != null)
125
				cursor.close();
126
		}
127
		return null;
128
	}
129
130
	/**
131
	 * @param uri
132
	 *            The Uri to check.
133
	 * @return Whether the Uri authority is ExternalStorageProvider.
134
	 */
135
	public static boolean isExternalStorageDocument(Uri uri) {
136
		return "com.android.externalstorage.documents".equals(uri
137
				.getAuthority());
138
	}
139
140
	/**
141
	 * @param uri
142
	 *            The Uri to check.
143
	 * @return Whether the Uri authority is DownloadsProvider.
144
	 */
145
	public static boolean isDownloadsDocument(Uri uri) {
146
		return "com.android.providers.downloads.documents".equals(uri
147
				.getAuthority());
148
	}
149
150
	/**
151
	 * @param uri
152
	 *            The Uri to check.
153
	 * @return Whether the Uri authority is MediaProvider.
154
	 */
155
	public static boolean isMediaDocument(Uri uri) {
156
		return "com.android.providers.media.documents".equals(uri
157
				.getAuthority());
158
	}
159
160
	/**
161
	 * @param uri
162
	 *            The Uri to check.
163
	 * @return Whether the Uri authority is Google Photos.
164
	 */
165
	public static boolean isGooglePhotosUri(Uri uri) {
166
		return "com.google.android.apps.photos.content".equals(uri
167
				.getAuthority());
168
	}
169
170
	public static String selectImage(Context context, Intent data) {
171
		Uri selectedImage = data.getData();
172
		// Log.e(TAG, selectedImage.toString());
173
		if (selectedImage != null) {
174
			String uriStr = selectedImage.toString();
175
			String path = uriStr.substring(10, uriStr.length());
176
			if (path.startsWith("com.sec.android.gallery3d")) {
177
				Log.e("path",
178
						"It's auto backup pic path:" + selectedImage.toString());
179
				return null;
180
			}
181
		}
182
		String[] filePathColumn = { MediaStore.Images.Media.DATA };
183
		Cursor cursor = context.getContentResolver().query(selectedImage,
184
				filePathColumn, null, null, null);
185
		cursor.moveToFirst();
186
		int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
187
		String picturePath = cursor.getString(columnIndex);
188
		cursor.close();
189
		return picturePath;
190
	}
191
192
}

+ 59 - 0
ipu-mail/src/com/ai/ipu/mail/util/ShareUtil.java

@ -0,0 +1,59 @@
1
package com.ai.ipu.mail.util;
2
3
import java.io.File;
4
5
import com.ai.ipu.basic.file.FileUtil;
6
import com.ai.ipu.mail.R;
7
import com.ai.ipu.mail.func.MailSender.OnTransportStateListener;
8
import com.ai.ipu.mail.func.SenderRunnable;
9
import com.ai.ipu.mobile.app.AppInfoUtil;
10
import com.ai.ipu.mobile.res.assets.AssetsUtil;
11
import com.ai.ipu.mobile.ui.HintUtil;
12
import com.wade.mobile.app.AppRecord;
13
14
import android.app.Activity;
15
import android.app.AlertDialog;
16
import android.content.ComponentName;
17
import android.content.Context;
18
import android.content.Intent;
19
import android.content.pm.PackageManager;
20
import android.content.pm.PackageManager.NameNotFoundException;
21
import android.net.Uri;
22
import android.view.View;
23
24
25
public class ShareUtil {
26
	
27
	private Context context;
28
29
	public String password;
30
31
	public ShareUtil(Context context) {
32
		this.context = context;
33
	}
34
35
	/**
36
	 * 发送图片到163邮箱
37
	 */
38
	public void shareImageBymail(String user, String password, OnTransportStateListener listener,String subject,
39
			String body, String receiver, String attachment) {
40
		SenderRunnable senderRunnable = new SenderRunnable(user, password, listener);
41
		senderRunnable.setMail(subject, body, receiver, attachment);
42
		new Thread(senderRunnable).start();
43
	}
44
	
45
	
46
	/**
47
	 * 初始化密码弹出框的布局
48
	 * @param resource 布局文件的资源id
49
	 * @param defaultView 如果为true表示使用默认布局
50
	 */
51
	public View initDialogView(int resource, boolean defaultView){
52
		if(defaultView){//使用默认布局
53
			return View.inflate(context, R.layout.dialog_set_userpwd, null);
54
		}else{
55
			//根据传入的resource初始化view
56
			return View.inflate(context, resource, null);
57
		}
58
	}
59
}