[Unity]Unity调用Jar包实现安装APK

        计划改不上变化,之前是平台强更APK,功能都已经完善了,都线上测试过。现在改成需要我们这边来操作,好吧,那就来研究下。

        跟之前一样,为了省事,安装APK的代码也放到之前写的jar包中。代码,其实很简单。但是 Android N为了安全考虑,需要使用 fileprovider 机制来访问、打开 APK 文件。这个地方就卡了我一个下午加晚上的时间来搞,记录一下。

Java代码:

    /**
     * 安装APK
     */
    public void InstallAPK(Object object, String apkPath)
    {
        Activity activity = (Activity)object;
        if(activity != null) {
            Intent installIntent = new Intent(Intent.ACTION_VIEW);
            installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            File apkFile = new File(apkPath);
            Uri uri;
            if(Build.VERSION.SDK_INT >= 24)
            {
                uri = FileProvider.getUriForFile(activity.getApplicationContext(), activity.getPackageName() + ".fileprovider", apkFile);
                installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            }else
                uri = Uri.fromFile(apkFile);
            installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
            activity.getApplicationContext().startActivity(installIntent);
        }
    }

AndroidManifest.xml上的修改:

<!-- 添加权限 -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

<application
        ---------------------------------------
         >
        
      <!-- authorities中的大小写要注意下 -->
      <provider
          android:name="android.support.v4.content.FileProvider"
          android:authorities="${applicationId}.fileprovider"
          android:grantUriPermissions="true"
          android:exported="false">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
      </provider>


       <activity
            ---------------------------------------
        </activity>
       
      
    </application>

        android:resource="@xml/file_paths",看到这个xml文件吗?你需要在Unity上添加这个xml文件。

目录:

file_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <paths>
    <external-path
        name="files"
        path="" />
	</paths>
</resources>

注意,踩坑的地方到了:

1.java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/content/FileProvider。如果报了这个错误,需要在Unity上添加android-support-v4.jar。看上面的截图。

2.java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourcePar错误。注意AndroidManifest.xml配置上android:authorities的名称是否对的,大小写也注意下

3.android.content.res.XmlResourceParser错误。跟第2个错误一样。

        其实就大小写的问题卡了很久,fileProvider和fileprovider不仔细看,还真不注意,记录下来,省的下次再犯这个错误。

C#上的测试代码:

public class Test : MonoBehaviour {

    AndroidJavaObject currentActivity;
    AndroidJavaClass apiClass;
    AndroidJavaObject apiInstance;

    /// <summary>
    /// 获取当前Activity
    /// </summary>
    /// <returns></returns>
    AndroidJavaObject GetCurrentActivity()
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        if (null == currentActivity)
            currentActivity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
#endif
        return currentActivity;
    }

    /// <summary>
    /// 获取安卓工具类实例
    /// </summary>
    /// <returns></returns>
    private AndroidJavaObject GetApiInstance()
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        if (null == apiInstance)
        {
            if (null == apiClass)
                apiClass = new AndroidJavaClass("com.zp.utility.api");
 
            apiInstance = apiClass.CallStatic<AndroidJavaObject>("instance");
        }
#endif
        return apiInstance;
    }

    void InstallAPK(string apkPath)
    {
        Debug.LogError("apkPath: " + apkPath);
#if UNITY_ANDROID && !UNITY_EDITOR
        var apiInstance = GetApiInstance();
        var activity = GetCurrentActivity();
        if(apiInstance != null && activity != null)
        {
            apiInstance.Call("InstallAPK", activity, apkPath);
        }
#endif
    }

    private void OnGUI()
    {
        if (GUI.Button(new Rect(0, 0, 100, 100), "InstallAPK"))
        {
            InstallAPK(Application.persistentDataPath + "/" + "test.apk");
        }
    }
}

        还查到个解决方法是在Application.onCreate加入如下代码,这个没有测试:

       StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
       StrictMode.setVmPolicy(builder.build());
       builder.detectFileUriExposure();

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值