免SDK實現微信/支付寶轉帳打賞功能

安卓開發者都應該有一個屬於本身的APP發佈到市場,能夠完善本身的技術站以外,加入廣告,還能夠有一份小收入。android

可是這個年代,各家的應用市場是不歡迎帶廣告sdk的我的開發者應用的。還好咱們能夠用插件技術加入廣告sdk,或者直接想一種方面實現打賞功能,讓用戶經過支付寶或微信轉帳到本身帳戶。git

免sdk實現 微信/支付寶 轉帳打賞功能

安卓我的開發者若是若是想着App裏實現支付打賞功能,嵌入sdk不說成本大外,基本是過不了市場審覈的。那麼咱們能夠利用有限資源,封裝組件實現一個mini型的打賞功能。github

1、支付寶轉帳分析

支付寶的轉帳和支付功能,均可以經過二維碼打開相關的支付頁面,而且用瀏覽器掃一掃後也是能夠正常呼起正常支付頁面的。那麼咱們簡單分析下,支付寶的二維碼整個跳轉確定不須要相關集成sdk的,那麼到底什麼樣的數據格式能夠作到的?數據庫

在支付寶我的信息頁,找到 個人二維碼,截圖本身的支付寶二維碼,識別下,獲得如下信息:canvas

qa

二維碼在線解析網址移步瀏覽器

能夠看到支付寶的支付二維碼就是一個普通的http url, 而後它主要信息就存在後綴字符: apafm3kp91df7yo517 裏。bash

https://qr.alipay.com/apafm3kp91df7yo517微信

網上查詢後,發現果真能夠經過scheme去打開支付寶轉帳頁面。參考app

ali

因而立刻動手實現,驗證scheme方式是有效的。剩下的就是怎麼封裝下方面調用。微信支付

2、微信轉帳分析

有了支付寶的轉帳經驗,咱們一樣從二維碼信息入手,發現微信隨着版本更新,會有不少驗證,直接用scheme調微信,會打開微信的一個空白網頁。

分析

而後研究裏下微信支付sdk,發如今接口調用的時間須要商戶id,及appsecret等信息驗證,這就意味這咱們單純的沒有任何身份信息去調起微信支付是不可能的。 那麼咱們退而求其次,用引導方式幫用戶直接打開微信掃一掃頁面,文案引導用戶從相冊打開二維碼,而後支付。

下一步,就是找到打開微信掃一掃的方法。

private void toWeChatScan() {
        try {
            //利用Intent打開微信
            Uri uri = Uri.parse("weixin://dl/scan");
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            startActivity(intent);
        } catch (Exception e) {
            //若沒法正常跳轉,在此進行錯誤處理
            Toast.makeText(DinpayWeChatActivity.this, "沒法跳轉到微信,請檢查您是否安裝了微信!", Toast.LENGTH_SHORT).show();
        }
    }
複製代碼

以上是網上推薦的方法,那麼很不幸的是,這種方法估計在很早以前版本能夠,可是如今這種方法是無效的

那麼是否是高版本就沒有方法裏呢?繼續google,發現如下方法是可行的:

/*package*/ static void startWechatScan(Context c) {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.tencent.mm", "com.tencent.mm.ui.LauncherUI"));
        intent.putExtra("LauncherUI.From.Scaner.Shortcut", true);
        intent.setFlags(335544320);
        intent.setAction("android.intent.action.VIEW");
    
        if (MiniPayUtils.isActivityAvailable(c, intent)) {
            c.startActivity(intent);
        } else {
            Toast.makeText(c, "未安裝微信~", Toast.LENGTH_SHORT).show();
        }
    }
複製代碼

二維碼微信相冊保存

實現微信掃一掃跳轉後,用戶在從相冊選擇二維碼時,怎麼樣才能一眼選出咱們的目標轉帳二維碼呢?

觀察發現微信的二維碼選擇相冊是按照時間順序排序,那麼只要咱們的圖片生成時間最新就能夠排在第一位,每次新生成截圖保存便可。

相關圖片生成及相冊保存邏輯以下:

/*package*/
    static void startWeZhi(Context c, View view) {
        File dir = c.getExternalFilesDir("pay_img");
        if (dir != null &&
                !dir.exists() && !dir.mkdirs()) {
            return;
        } else {
            File[] f = dir.listFiles();
            for (File file : f) {
                file.delete();//刪除舊截圖,每次用新截圖,保證相冊排序。
            }
        }

        String fileName = System.currentTimeMillis() + "weixin_qa.png";
        File file = new File(dir, fileName);
        if (!file.exists()) {
            file.delete();
        }

        snapShot(c, file, view);
        startWechat(c);
    }

	/**
	  * 截圖保存邏輯
	  */
    private static void snapShot(Context context, @NonNull File file, @NonNull View view) {
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas();
        canvas.setBitmap(bitmap);
        view.draw(canvas);

        FileOutputStream fos = null;
        boolean isSuccess = false;
        try {
            fos = new FileOutputStream(file);
            //經過io流的方式來壓縮保存圖片
            isSuccess = bitmap.compress(Bitmap.CompressFormat.PNG, 80, fos);
            fos.flush();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            MiniPayUtils.closeIO(fos);
        }
        if (isSuccess) {
            ContentResolver contentResolver = context.getContentResolver();
            ContentValues values = new ContentValues(4);
            values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
            values.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
            values.put(MediaStore.Images.Media.ORIENTATION, 0);
            values.put(MediaStore.Images.Media.TITLE, "捐贈");
            values.put(MediaStore.Images.Media.DESCRIPTION, "捐贈二維碼");
            values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
            values.put(MediaStore.Images.Media.DATE_MODIFIED,System.currentTimeMillis()/1000);
            Uri url = null;

            try {
                url = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); //其實質是返回 Image.Meida.DATA中圖片路徑path的轉變而成的uri
                OutputStream imageOut = contentResolver.openOutputStream(url);
                try {
                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, imageOut);
                } finally {
                    MiniPayUtils.closeIO(imageOut);
                }

                long id = ContentUris.parseId(url);
                MediaStore.Images.Thumbnails.getThumbnail(contentResolver, id, MediaStore.Images.Thumbnails.MINI_KIND, null);//獲取縮略圖

            } catch (Exception e) {
                if (url != null) {
                    contentResolver.delete(url, null, null);
                }
            }
        }
    }
複製代碼

這裏涉及到屏幕截圖保存邏輯,須要指定截圖範圍,保存後,還須要通知系統媒體數據庫(微信圖片的獲取應該是讀取的系統媒體庫),保證數據更新。

wechat

3、封裝sdk

既然能夠實現免sdk的支付打賞功能,那麼咱們把這個功能封裝成一個sdk,方便項目的植入。

那麼本者 方便引入、簡單使用,體驗好等原則,實現了MiniPay開源項目

項目把微信和支付寶集成了一個支付頁面,點擊背景可切換打賞途徑。

wechat

ali

只要一行代碼便可引入本身項目

compile 'com.canking.minipay:minipay:1.0.x'
複製代碼

只要一行即個啓動MiniPay打賞組件

MiniPayUtils.setupPay(this, config);
複製代碼

代碼徹底開放,源碼傳送門,能夠徹底自定意邏輯。

Get it on Google Play


歡迎轉載,請標明出處:常興E站 canking.win

相關文章
相關標籤/搜索