Android 第三方应用市场如何绕过手机厂商对apk的检测

要绕过手机厂商对于安装apk的检测无非就是在apk下载完成安装时切断用户的网络(这个期间一般也就10s左右的时间安装apk完成的时间也和这个差多不这个视手机而定),so 要实现这样的效果,首先想到的是切断用户的手机网络,但实际的开发中这样做还是有一大堆的问题。之后偶然的发现了通过vpn的这种方式来实现。可以解决这样的问题只是用户在第一次安装的时候让用户选择开启VPN就哦了。如果看到的童鞋有更好的想法欢迎拍砖。
要使用vpn的话用到的是VpnService 这个类是在android.net.VpnService 包底下如图
官网链接
这里写图片描述

OK代码如下:
1.创建一个MyVpnService


import android.content.Intent;
import android.net.VpnService;
import android.os.ParcelFileDescriptor;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.InetSocketAddress;
import java.nio.channels.DatagramChannel;

/**
 * Created by vc on 2017/6/28.
 */

public class MyVpnService extends VpnService {


    private Thread mThread;

    private ParcelFileDescriptor  mParcelFileDescriptor;


    private Builder  mBuilder =new Builder(); // VpnService.Builder





    @Override
    public int onStartCommand(Intent intent,int flags, int startId) {

        final boolean  flag = intent.getBooleanExtra("showtime",true);

        mThread =new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    mParcelFileDescriptor = mBuilder.setSession("myVpnService") // 给session设置一个名称

                                            .addAddress("192.168.0.1",24)//给vpn的接口添加一个地址

                                            .addDnsServer("8.8.8.8") //添加一个dns的服务给vpn

                                            .addRoute("0.0.0.0",0)//将网络路由器器添加到vpn的接口

                                            .establish() ;  //表示使用此构建器的参数创建vpn的接口


                    FileInputStream inputStream = new FileInputStream(mParcelFileDescriptor.getFileDescriptor());  // 发送数据包排队在这个输入流上

                    FileOutputStream out = new FileOutputStream( mParcelFileDescriptor.getFileDescriptor());  //接收到的数据包写入输出流


                    //DatagramChannel 是一个能收发UDP包的通道。因为UDP是无连接的网络协议,所以不能像其它通道那样读取和写入。它发送和接收的是数据包。

                    DatagramChannel datagramChannel =DatagramChannel.open();

                    datagramChannel.connect(new InetSocketAddress("127.0.0.1",8087));

                    protect(datagramChannel.socket());  // 保护socket 与vpn链接

                    /*if(flag){
                        while (true) {  //循环传输数据包

                            Thread.sleep(100);
                        }
                    }else {

                        Thread.sleep(10000);
                    }*/

                Thread.sleep(10000); // 这里定义了一个时间



                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                     try {
                      if(mParcelFileDescriptor!=null){
                          mParcelFileDescriptor.close();
                          mParcelFileDescriptor=null;
                      }


                    }catch (Exception e ){
                        e.printStackTrace();
                    }

                }


            }
        });

        mThread.start();

        return START_NOT_STICKY;
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
         if(mThread!=null){
             mThread.interrupt();
         }

    }
}

2,在Androidmanifest.xml 注册当前的MyVpnService

 <service
            android:name=".MyVpnService"
            android:permission="android.permission.BIND_VPN_SERVICE">
            <intent-filter>
                <action android:name="android.net.VpnService"/>
            </intent-filter>
        </service>

3.到此主要的vpnservice 已经完成了。接下来是打开vpnservice,主要代码如下:

 Intent intent = VpnService.prepare(InstallActivity.this);//准备vpnservice的连接

        if(intent!=null){

            startActivityForResult(intent,0);
        }else {

            onActivityResult(0,RESULT_OK,null);
        }

处理结果需要在onActivityResult中

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

       Log.e(TAG,"onActivityResult");
        if(resultCode== RESULT_OK){
            Intent intent = new Intent(this,MyVpnService.class);
            startService(intent);

        }

    }

这样就可以开启一个vpn的service了。走到这里你可能觉得这不就是一个开启vpnservice么,别忘了我们要做的是安装apk的时候绕过厂商特殊机型的对apk的检测,有一种解决思路就是每次安装apk的时候都走一个installActivity 这个activity是透明的切只有一个像素的大小


import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.Uri;
import android.net.VpnService;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import android.view.WindowManager;

import java.io.File;


// 安装app的activity
public class InstallActivity extends Activity {

    private boolean isShow= true;  // 用于判断当前activity的显示状态

    private MyVpnService mMyVpnService;

   private final  String TAG="InstallActivity";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.e(TAG,"onCreate");

        //设置activity的大小
        WindowManager.LayoutParams  params = getWindow().getAttributes();
        params.width = 1;
        params.height = 1;
        params.dimAmount= 0.0f;
        getWindow().setAttributes(params);

         Intent intent = VpnService.prepare(InstallActivity.this);

        if(intent!=null){

            startActivityForResult(intent,0);
        }else {

            onActivityResult(0,RESULT_OK,null);
        }



    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.e(TAG,"onResume");
        if(!isShow){
             Log.e(TAG,"onResume finish ");
            finish();
         }


    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onPause() {
        super.onPause();
        isShow =false;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e(TAG,"onDestroy");

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

       Log.e(TAG,"onActivityResult");
        if(resultCode== RESULT_OK){
            isShow =false;
            Intent intent = new Intent(this,MyVpnService.class);
            startService(intent);

//处理完成后安装apk这里写个一个本地路径实际开发中需要传入安装apk的路径
          inStallApp(Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"q.apk");

        }

    }




    private void inStallApp(String path){

        Uri uri = Uri.fromFile(new File(path));

        Intent intent = new Intent(Intent.ACTION_VIEW);

        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        intent.setDataAndType(uri,"application/vnd.android.package-archive");

       startActivity(intent);

    }


}

设置activity透明的主题

 <style name="transparent_theme" parent="@android:style/Theme.Translucent.NoTitleBar"></style>

需要注意的就是installactivity需求继承activity否则这么干会报错的。这里只能算是一种解决思路实际中对于不同的厂商哪些是对apk安装检测的还需要去统计不同的机型。如果有更好的想法欢迎拍砖

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值