編輯:關於Android編程
// 商戶PID public static final String PARTNER = "2088811977704990"; // 商戶收款賬號 public static final String SELLER = "[email protected]"; // 商戶私鑰,pkcs8格式 public static final String RSA_PRIVATE = "MIICXQIBAAKBgQDlQ468L1A7Q+GG80/Z8f3IsSiiFIluSxfTTSuJ/XSPzvYS+bMZ" +"AQLMqq/nGhkp+1Q5pHF9LAQtQS3gL2pqzbKdtvZSsy/tNFFQcGCsgK2ygMl+MW/F" +"g/ufx7c1jy1kZAeDyl1m302dnRrtSgDalkgH7FKRcmDxbXPTnFGHbg9zMQIDAQAB" +"AoGAa28wGQF28H7L1Yh5V+FtkrlqGCHVkQjBfnRAPea205kheRzoD4SIwk4OJhb1" +"ydWLz4M+53BT+Lz9eXveu3PvCdQe9zMIVC5dKUNVYCvvcHZ+Ot8HriiuwGPb3Quu" +"twbnLGM5gxxPDo0yUyWrfaVn/qR35mS6TDfmgowVG8CmBpECQQDzuhodR/Jgxrtn" +"tka+88alyy+BfjUZqNloPuE7JfXrpOxH5lodk7Y4lTki/dlo5BrK+hrismLFr9Du" +"ueAJ7G9dAkEA8M8C6VnpUMAK5+rYcjKnQssDqcMfurKYEil1BD/TUdSbLI6v8p02" +"mv1ApuTVtQQypZJKIFfurGk0g0QlvzLZ5QJAGfY38+iHDAH/UnPbI1oKTfzPyaZs" +"95fB2NXh3hAUGw7NUHdcIAxs+6gBlxWdRAwQQpDTrlQ8KzyoL9XC5Ku3zQJBALO8" +"j5vEtFTFQl6f9zYlgJpmFTHcpg4fx0mnD+RAD2aAneHADquzlFJSvLLVEn2tyG+0" +"pQdHGqotTDi94L65IdECQQDb1h+5kugCu47IxsDkrLRsKVcr8dSDMORyeT1L0HWR" +"ctramBu+2PBz2UKC6+9dQ+ZQH4XTKpBSvkyZH4mYi1de"; // // 支付寶公鑰 // public static final String RSA_PUBLIC = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnxj/9qwVfgoUh/y2W89L6BkRAFljhNhgPdyPuBV64bfQNN1PjbCzkIM6qRdKBoLPXmKKMiFYnkd6rAoprih3/PrQEB/VsW8OoM8fxn67UDYuyBTqA23MML9q1+ilIZwBC2AQ2UBVOrFXfFl75p6/B5KsiNG9zpgmLCUYuLkxpLQIDAQAB";
import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.Random; import com.alipay.sdk.app.PayTask; import com.example.exmpay.alipay.bean.AlipayConstants; import com.example.exmpay.alipay.bean.PayResult; import com.example.exmpay.alipay.util.SignUtils; import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.os.AsyncTask; import android.text.TextUtils; import android.widget.Toast; public class AlipayTask extends AsyncTask{ private static final String TAG = "AlipayTask"; private Context context; private ProgressDialog dialog; public AlipayTask(Context context) { this.context = context; } @Override protected void onPreExecute() { if (TextUtils.isEmpty(AlipayConstants.PARTNER) || TextUtils.isEmpty(AlipayConstants.RSA_PRIVATE) || TextUtils.isEmpty(AlipayConstants.SELLER)) { new AlertDialog.Builder(context).setTitle("警告").setMessage("需要配置PARTNER | RSA_PRIVATE| SELLER") .setPositiveButton("確定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialoginterface, int i) { } }).show(); cancel(true); } else { dialog = ProgressDialog.show(context, "提示", "正在啟動支付寶..."); } } @Override protected String doInBackground(Void... params) { String orderInfo = getOrderInfo("測試的商品", "該測試商品的詳細描述", "0.01"); //特別注意,這裡的簽名邏輯需要放在服務端,切勿將私鑰洩露在代碼中! String sign = sign(orderInfo); try { //僅需對sign 做URL編碼 sign = URLEncoder.encode(sign, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } //完整的符合支付寶參數規范的訂單信息 final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType(); // 構造PayTask 對象 PayTask alipay = new PayTask((Activity) context); // 調用支付接口,獲取支付結果 String result = alipay.pay(payInfo, false); return result; } @Override protected void onPostExecute(String result) { if (dialog != null) { dialog.dismiss(); } PayResult payResult = new PayResult(result); // 支付寶返回此次支付結果及加簽,建議對支付寶簽名信息拿簽約時支付寶提供的公鑰做驗簽 String resultInfo = payResult.getResult(); Toast.makeText(context, "resultInfo="+resultInfo, Toast.LENGTH_SHORT).show(); String resultStatus = payResult.getResultStatus(); // 判斷resultStatus 為“9000”則代表支付成功,具體狀態碼代表含義可參考接口文檔 if (TextUtils.equals(resultStatus, "9000")) { Toast.makeText(context, "支付寶繳費成功", Toast.LENGTH_SHORT).show(); } else { // 判斷resultStatus 為非“9000”則代表可能支付失敗 // “8000”代表支付結果因為支付渠道原因或者系統原因還在等待支付結果確認,最終交易是否成功以服務端異步通知為准(小概率狀態) if (TextUtils.equals(resultStatus, "8000")) { Toast.makeText(context, "支付寶繳費結果確認中", Toast.LENGTH_SHORT).show(); } else { // 其他值就可以判斷為支付失敗,包括用戶主動取消支付,或者系統返回的錯誤 Toast.makeText(context, "支付寶繳費失敗"+payResult.getResult(), Toast.LENGTH_SHORT).show(); } } } private String getOrderInfo(String subject, String body, String price) { // 簽約合作者身份ID String orderInfo = "partner=" + "\"" + AlipayConstants.PARTNER + "\""; // 簽約賣家支付寶賬號 orderInfo += "&seller_id=" + "\"" + AlipayConstants.SELLER + "\""; // 商戶網站唯一訂單號 orderInfo += "&out_trade_no=" + "\"" + getOutTradeNo() + "\""; // 商品名稱 orderInfo += "&subject=" + "\"" + subject + "\""; // 商品詳情 orderInfo += "&body=" + "\"" + body + "\""; // 商品金額 orderInfo += "&total_fee=" + "\"" + price + "\""; // 服務器異步通知頁面路徑 orderInfo += "¬ify_url=" + "\"" + "http://notify.msp.hk/notify.htm" + "\""; // 服務接口名稱, 固定值 orderInfo += "&service=\"mobile.securitypay.pay\""; // 支付類型, 固定值 orderInfo += "&payment_type=\"1\""; // 參數編碼, 固定值 orderInfo += "&_input_charset=\"utf-8\""; // 設置未付款交易的超時時間,默認30分鐘,一旦超時,該筆交易就會自動被關閉。 // 取值范圍:1m~15d。m-分鐘,h-小時,d-天,1c-當天(無論交易何時創建,都在0點關閉)。 // 該參數數值不接受小數點,如1.5h,可轉換為90m。 orderInfo += "&it_b_pay=\"30m\""; // extern_token為經過快登授權獲取到的alipay_open_id,帶上此參數用戶將使用授權的賬戶進行支付 // orderInfo += "&extern_token=" + "\"" + extern_token + "\""; // 支付寶處理完請求後,當前頁面跳轉到商戶指定頁面的路徑,可空 orderInfo += "&return_url=\"m.alipay.com\""; // 調用銀行卡支付,需配置此參數,參與簽名, 固定值 (需要簽約《無線銀行卡快捷支付》才能使用) // orderInfo += "&paymethod=\"expressGateway\""; return orderInfo; } private String getOutTradeNo() { SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault()); Date date = new Date(); String key = format.format(date); Random r = new Random(); key = key + r.nextInt(); key = key.substring(0, 15); return key; } private String sign(String content) { return SignUtils.sign(content, AlipayConstants.RSA_PRIVATE); } private String getSignType() { return "sign_type=\"RSA\""; } }
// APP_ID 替換為你的應用從官方網站申請到的合法appId public static final String APP_ID = "wxd930ea5d5a258f4f"; public static final String APP_SECRET = "db426a9829e4b49a0dcac7b4162da6b6"; // wxd930ea5d5a258f4f 對應的支付密鑰 public static final String APP_KEY = "L8LrMqqeGRxST5reouB0K66CaYAWpqhAVsq7ggKkxHCOastWksvuX1uvmvQclxaHoYd3ElNBrNO2DHnnzgfVG9Qs473M3DTOZug5er46FhuGofumV8H2FVR9qkjSlC5K"; /** 商家向財付通申請的商家id */ public static final String PARTNER_ID = "1900000109"; public static final String PARTNER_KEY = "8934e7d15453e97507ef794cf7b0519d";
import com.example.exmpay.wechat.bean.WechatConstants; import com.example.exmpay.wechat.bean.GetAccessTokenResult; import com.example.exmpay.wechat.bean.LocalRetCode; import com.example.exmpay.wechat.util.WechatUtil; import android.app.ProgressDialog; import android.content.Context; import android.os.AsyncTask; import android.util.Log; import android.widget.Toast; public class GetAccessTokenTask extends AsyncTask{ private static final String TAG = "GetAccessTokenTask"; private Context context; private ProgressDialog dialog; public GetAccessTokenTask(Context context) { this.context = context; } @Override protected void onPreExecute() { dialog = ProgressDialog.show(context, "提示", "正在獲取access token..."); } @Override protected GetAccessTokenResult doInBackground(Void... params) { GetAccessTokenResult result = new GetAccessTokenResult(); String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", WechatConstants.APP_ID, WechatConstants.APP_SECRET); Log.d(TAG, "get access token, url = " + url); byte[] buf = WechatUtil.httpGet(url); if (buf == null || buf.length == 0) { result.localRetCode = LocalRetCode.ERR_HTTP; return result; } String content = new String(buf); result.parseFrom(content); return result; } @Override protected void onPostExecute(GetAccessTokenResult result) { if (dialog != null) { dialog.dismiss(); } if (result.localRetCode == LocalRetCode.ERR_OK) { Toast.makeText(context, "獲取access token成功, accessToken = " + result.accessToken, Toast.LENGTH_LONG).show(); GetPrepayIdTask getPrepayId = new GetPrepayIdTask(context, result.accessToken); getPrepayId.execute(); } else { Toast.makeText(context, "獲取access token失敗,原因: " + result.localRetCode.name(), Toast.LENGTH_LONG).show(); } } }
import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Random; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.message.BasicNameValuePair; import com.alibaba.fastjson.JSONObject; import com.example.exmpay.wechat.bean.WechatConstants; import com.example.exmpay.wechat.bean.GetPrepayIdResult; import com.example.exmpay.wechat.bean.LocalRetCode; import com.example.exmpay.wechat.util.MD5; import com.example.exmpay.wechat.util.WechatUtil; import com.tencent.mm.sdk.modelpay.PayReq; import com.tencent.mm.sdk.openapi.IWXAPI; import com.tencent.mm.sdk.openapi.WXAPIFactory; import android.app.ProgressDialog; import android.content.Context; import android.os.AsyncTask; import android.util.Log; import android.widget.Toast; public class GetPrepayIdTask extends AsyncTask{ private static final String TAG = "GetPrepayIdTask"; private Context context; private ProgressDialog dialog; private String accessToken; public GetPrepayIdTask(Context context, String accessToken) { this.context = context; this.accessToken = accessToken; } @Override protected void onPreExecute() { dialog = ProgressDialog.show(context, "提示", "正在獲取預支付訂單..."); } @Override protected GetPrepayIdResult doInBackground(Void... params) { String url = String.format("https://api.weixin.qq.com/pay/genprepay?access_token=%s", accessToken); String entity = genProductArgs(); Log.d(TAG, "doInBackground, url = " + url + ", entity = " + entity); GetPrepayIdResult result = new GetPrepayIdResult(); byte[] buf = WechatUtil.httpPost(url, entity); if (buf == null || buf.length == 0) { result.localRetCode = LocalRetCode.ERR_HTTP; return result; } String content = new String(buf); Log.d(TAG, "doInBackground, response content = " + content); result.parseFrom(content); return result; } @Override protected void onPostExecute(GetPrepayIdResult result) { if (dialog != null) { dialog.dismiss(); } if (result.localRetCode == LocalRetCode.ERR_OK) { Toast.makeText(context, "獲取prepayid成功", Toast.LENGTH_LONG).show(); payWithWechat(result); } else { Toast.makeText(context, "獲取prepayid失敗,原因"+result.localRetCode.name(), Toast.LENGTH_LONG).show(); } } private IWXAPI mWeixinApi; // // 如果獲取token和預付標識在服務器實現,只留下支付動作在客戶端實現,那麼下面要異步調用 // private void payWithWechat() { // final String payInfo = ""; // // Runnable payRunnable = new Runnable() { // @Override // public void run() { // sendWXPayReq(payInfo); // } // }; // // Thread payThread = new Thread(payRunnable); // payThread.start(); // } private String genPackage(List params) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < params.size(); i++) { sb.append(params.get(i).getName()); sb.append('='); sb.append(params.get(i).getValue()); sb.append('&'); } sb.append("key="); sb.append(WechatConstants.PARTNER_KEY); // 注意:不能hardcode在客戶端,建議genPackage這個過程都由服務器端完成 // 進行md5摘要前,params內容為原始內容,未經過url encode處理 String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase(Locale.getDefault()); return URLEncodedUtils.format(params, "utf-8") + "&sign=" + packageSign; } private String genNonceStr() { Random random = new Random(); return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes()); } private long genTimeStamp() { return System.currentTimeMillis() / 1000; } private String getTraceId() { return "crestxu_" + genTimeStamp(); } private String genOutTradNo() { Random random = new Random(); return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes()); } private long timeStamp; private String nonceStr, packageValue; private String genSign(List params) { StringBuilder sb = new StringBuilder(); int i = 0; for (; i < params.size() - 1; i++) { sb.append(params.get(i).getName()); sb.append('='); sb.append(params.get(i).getValue()); sb.append('&'); } sb.append(params.get(i).getName()); sb.append('='); sb.append(params.get(i).getValue()); String sha1 = WechatUtil.sha1(sb.toString()); Log.d(TAG, "genSign, sha1 = " + sha1); return sha1; } private String genProductArgs() { JSONObject json = new JSONObject(); try { json.put("appid", WechatConstants.APP_ID); String traceId = getTraceId(); // traceId 由開發者自定義,可用於訂單的查詢與跟蹤,建議根據支付用戶信息生成此id json.put("traceid", traceId); nonceStr = genNonceStr(); json.put("noncestr", nonceStr); List packageParams = new LinkedList (); packageParams.add(new BasicNameValuePair("bank_type", "WX")); packageParams.add(new BasicNameValuePair("body", "千足金箍棒")); packageParams.add(new BasicNameValuePair("fee_type", "1")); packageParams.add(new BasicNameValuePair("input_charset", "UTF-8")); packageParams.add(new BasicNameValuePair("notify_url", "http://weixin.qq.com")); packageParams.add(new BasicNameValuePair("out_trade_no", genOutTradNo())); packageParams.add(new BasicNameValuePair("partner", WechatConstants.PARTNER_ID)); packageParams.add(new BasicNameValuePair("spbill_create_ip", "196.168.1.1")); packageParams.add(new BasicNameValuePair("total_fee", "1")); packageValue = genPackage(packageParams); json.put("package", packageValue); timeStamp = genTimeStamp(); json.put("timestamp", timeStamp); List signParams = new LinkedList (); signParams.add(new BasicNameValuePair("appid", WechatConstants.APP_ID)); signParams.add(new BasicNameValuePair("appkey", WechatConstants.APP_KEY)); signParams.add(new BasicNameValuePair("noncestr", nonceStr)); signParams.add(new BasicNameValuePair("package", packageValue)); signParams.add(new BasicNameValuePair("timestamp", String.valueOf(timeStamp))); signParams.add(new BasicNameValuePair("traceid", traceId)); json.put("app_signature", genSign(signParams)); json.put("sign_method", "sha1"); } catch (Exception e) { Log.e(TAG, "genProductArgs fail, ex = " + e.getMessage()); return null; } return json.toString(); } private void payWithWechat(GetPrepayIdResult result) { PayReq req = new PayReq(); req.appId = WechatConstants.APP_ID; req.partnerId = WechatConstants.PARTNER_ID; req.prepayId = result.prepayId; req.nonceStr = nonceStr; req.timeStamp = String.valueOf(timeStamp); req.packageValue = "Sign=" + packageValue; List signParams = new LinkedList (); signParams.add(new BasicNameValuePair("appid", req.appId)); signParams.add(new BasicNameValuePair("appkey", WechatConstants.APP_KEY)); signParams.add(new BasicNameValuePair("noncestr", req.nonceStr)); signParams.add(new BasicNameValuePair("package", req.packageValue)); signParams.add(new BasicNameValuePair("partnerid", req.partnerId)); signParams.add(new BasicNameValuePair("prepayid", req.prepayId)); signParams.add(new BasicNameValuePair("timestamp", req.timeStamp)); req.sign = genSign(signParams); mWeixinApi = WXAPIFactory.createWXAPI(context, WechatConstants.APP_ID); // 在支付之前,如果應用沒有注冊到微信,應該先調用IWXMsg.registerApp將應用注冊到微信 mWeixinApi.sendReq(req); } }
import net.sourceforge.simcpux.R; import com.example.exmpay.wechat.bean.WechatConstants; import com.tencent.mm.sdk.constants.ConstantsAPI; import com.tencent.mm.sdk.modelbase.BaseReq; import com.tencent.mm.sdk.modelbase.BaseResp; import com.tencent.mm.sdk.modelbase.BaseResp.ErrCode; import com.tencent.mm.sdk.openapi.IWXAPI; import com.tencent.mm.sdk.openapi.IWXAPIEventHandler; import com.tencent.mm.sdk.openapi.WXAPIFactory; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.widget.TextView; import android.widget.Toast; public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler { private static final String TAG = "WXPayEntryActivity"; private IWXAPI api; private TextView tv_result; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.pay_result); tv_result = (TextView) findViewById(R.id.tv_result); api = WXAPIFactory.createWXAPI(this, WechatConstants.APP_ID); api.handleIntent(getIntent(), this); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); api.handleIntent(intent, this); } @Override public void onReq(BaseReq req) { } @Override public void onResp(BaseResp resp) { Log.d(TAG, "onResp, errCode = " + resp.errCode); String result = ""; if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) { switch (resp.errCode) { case ErrCode.ERR_OK: result = "微信支付成功"; break; case ErrCode.ERR_COMM: result = "微信支付失敗:"+resp.errCode+","+resp.errStr; break; case ErrCode.ERR_USER_CANCEL: result = "微信支付取消:"+resp.errCode+","+resp.errStr; break; default: result = "微信支付未知異常:"+resp.errCode+","+resp.errStr; break; } } Toast.makeText(this, result, Toast.LENGTH_LONG).show(); tv_result.setText(result); } }
4、在啟動銀聯支付的Activity代碼中,重寫方法onActivityResult,對支付結果的返回包進行驗證處理;
銀行卡號:6226090000000048 手機號:18100000000 短信驗證碼:123456(先點獲取驗證碼之後再輸入)
import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import org.json.JSONException; import org.json.JSONObject; import com.example.exmpay.unionpay.bean.UnionpayConstants; import com.unionpay.UPPayAssistEx; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.os.AsyncTask; import android.util.Log; import android.widget.Toast; public class UnionpayTask extends AsyncTask{ private static final String TAG = "UnionpayTask"; private Context context; private ProgressDialog dialog; public static final int PLUGIN_VALID = 0; public static final int PLUGIN_NOT_INSTALLED = -1; public static final int PLUGIN_NEED_UPGRADE = 2; public UnionpayTask(Context context) { this.context = context; } @Override protected void onPreExecute() { dialog = ProgressDialog.show(context, "提示", "正在啟動銀聯支付..."); } @Override protected String doInBackground(Void... params) { Log.d(TAG, "doInBackground"); String tn = null; InputStream is; try { String url = UnionpayConstants.TN_URL_01; URL myURL = new URL(url); URLConnection ucon = myURL.openConnection(); ucon.setConnectTimeout(120000); is = ucon.getInputStream(); int i = -1; ByteArrayOutputStream baos = new ByteArrayOutputStream(); while ((i = is.read()) != -1) { baos.write(i); } tn = baos.toString(); is.close(); baos.close(); } catch (Exception e) { e.printStackTrace(); } Log.d(TAG, "tn="+tn); return tn; } @Override protected void onPostExecute(String tn) { if (dialog != null) { dialog.dismiss(); } startpay(tn); UPPayAssistEx.startPay(context, null, null, tn, UnionpayConstants.MODE); } public static void dealResult(Context context, Intent data) { if (data == null) { return; } String msg = ""; //支付控件返回字符串:success、fail、cancel 分別代表支付成功,支付失敗,支付取消 String str = data.getExtras().getString("pay_result"); if (str.equalsIgnoreCase("success")) { // 支付成功後,extra中如果存在result_data,取出校驗 // result_data結構見c)result_data參數說明 if (data.hasExtra("result_data")) { String result = data.getExtras().getString("result_data"); Log.d(TAG, "result="+result); try { JSONObject resultJson = new JSONObject(result); String sign = resultJson.getString("sign"); String dataOrg = resultJson.getString("data"); // 驗簽證書同後台驗簽證書 // 此處的verify,商戶需送去商戶後台做驗簽 boolean ret = verify(dataOrg, sign, UnionpayConstants.MODE); if (ret) { // 驗證通過後,顯示支付結果 msg = "銀聯支付成功"; } else { // 驗證不通過後的處理 // 建議通過商戶後台查詢支付結果 msg = "銀聯支付失敗:驗證失敗"; } } catch (JSONException e) { } } else { // 未收到簽名信息 // 建議通過商戶後台查詢支付結果 msg = "銀聯支付成功,但未收到簽名信息"; } } else if (str.equalsIgnoreCase("fail")) { msg = "銀聯支付失敗"; } else if (str.equalsIgnoreCase("cancel")) { msg = "銀聯支付取消"; } Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); } private int startpay(String tn) { //商戶後台要保存交易流水號 return 0; } private static boolean verify(String msg, String sign64, String mode) { // 此處的verify,商戶需送去商戶後台做驗簽 return true; } }
我們編寫的是Andorid的HTTP協議多線程斷點下載應用程序。直接使用單線程下載HTTP文件對我們來說是一件非常簡單的事。那麼,多線程斷點需要什麼功能?1.多線程下載,
在一些Android應用的開發中,需要通過JNI和Android NDK工具實現JAVA和C/C++之間的相互調用。Java Native Interface (JNI)
概要 當手機Modem狀態改變後會將狀態變化信息通知到上層,通過《Android 4.4 Kitkat Phone工作流程淺析(八)__Phone狀態分析》
社會化分享社會化分享,指的是用戶通過互聯網這個媒介,把文本/圖片/多媒體信息分享到該用戶的交際圈,從而加快信息傳播的行為。對於app來說,網絡社區雖多,但用戶量足夠大的就