分类: Android

  • 使用uniapp离线打包底座时获取getApplicationContext()的方法

    在对应的类中静态引入以下方法即可:

    import static io.dcloud.common.util.ReflectUtils.getApplicationContext;

    然后再对应的业务逻辑中直接使用getApplicationContext()即可获取到。

    事实上我用jd-gui查看其编译后代码,看见好像这种工具类也能自己写,其代码如下(未验证过):

    import android.context.Context;
    
    public static Context getApplicationContext(){
    	Context context = null;
    	try{
    		Context = (Context)Class.forName("android.app.ActivityThread").getDeclaredMethod("currentApplication",new Class[0]).invoke((Object)null, new Object[0]);
    	}catch(Exception e){
    		null.printStackTrace();
    	}
    }

     

  • Android调用原生文件管理器来选择文件

    在activity即可:

    public class UploadActivity  extends Activity {
    
        public final static int REQUEST_CODE = 1000;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
            intent.setType("*/*"); //设置类型,任意类型
            intent.addCategory(Intent.CATEGORY_OPENABLE);
    
            this.startActivityForResult(intent, REQUEST_CODE);
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            //if (requestCode == REQUEST_CODE && resultCode == 200) {
            if (data == null) {
                // 用户未选择任何文件,直接返回
                return;
            }
    
            Uri uri = data.getData(); // 获取用户选择文件的URI
    
            String path =  uri.getPath();
            Toast.makeText(this, "path="+path, Toast.LENGTH_SHORT).show();
            
            String truePath = this.getPath(this,uri);
            Toast.makeText(this, "truePath="+truePath, Toast.LENGTH_SHORT).show();
    
            File file = new File(truePath);
            Toast.makeText(this, "file.exists()="+file.exists(), Toast.LENGTH_SHORT).show();
    
            Intent intent = new Intent();
            intent.putExtra("truePath", truePath);
            setResult(Activity.RESULT_OK, intent);
            finish();
    
        }
    
        /**
         * 专为Android4.4设计的从Uri获取文件绝对路径,以前的方法已不好使
         */
        @SuppressLint("NewApi")
        public String getPath(final Context context, final Uri uri) {
    
            final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
    
            // DocumentProvider
            if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
                // ExternalStorageProvider
                if (isExternalStorageDocument(uri)) {
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];
    
                    if ("primary".equalsIgnoreCase(type)) {
                        return Environment.getExternalStorageDirectory() + "/" + split[1];
                    }
                }
                // DownloadsProvider
                else if (isDownloadsDocument(uri)) {
    
                    final String id = DocumentsContract.getDocumentId(uri);
                    final Uri contentUri = ContentUris.withAppendedId(
                            Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
    
                    return getDataColumn(context, contentUri, null, null);
                }
                // MediaProvider
                else if (isMediaDocument(uri)) {
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];
    
                    Uri contentUri = null;
                    if ("image".equals(type)) {
                        contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                    } else if ("video".equals(type)) {
                        contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                    } else if ("audio".equals(type)) {
                        contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                    } else if ("document".equals(type)) {
                        contentUri = MediaStore.Files.getContentUri("external");
                    }
    
                    final String selection = "_id=?";
                    final String[] selectionArgs = new String[]{split[1]};
    
                    return getDataColumn(context, contentUri, selection, selectionArgs);
                }
            }
            // MediaStore (and general)
            else if ("content".equalsIgnoreCase(uri.getScheme())) {
                return getDataColumn(context, uri, null, null);
            }
            // File
            else if ("file".equalsIgnoreCase(uri.getScheme())) {
                return uri.getPath();
            }
            return null;
        }
    
        /**
         * Get the value of the data column for this Uri. This is useful for
         * MediaStore Uris, and other file-based ContentProviders.
         *
         * @param context       The context.
         * @param uri           The Uri to query.
         * @param selection     (Optional) Filter used in the query.
         * @param selectionArgs (Optional) Selection arguments used in the query.
         * @return The value of the _data column, which is typically a file path.
         */
        public String getDataColumn(Context context, Uri uri, String selection,
                                    String[] selectionArgs) {
    
            Cursor cursor = null;
            final String column = "_data";
            final String[] projection = {column};
    
            try {
                cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                        null);
                if (cursor != null && cursor.moveToFirst()) {
                    final int column_index = cursor.getColumnIndexOrThrow(column);
                    return cursor.getString(column_index);
                }
            } finally {
                if (cursor != null)
                    cursor.close();
            }
            return null;
        }
    
        /**
         * @param uri The Uri to check.
         * @return Whether the Uri authority is ExternalStorageProvider.
         */
        public boolean isExternalStorageDocument(Uri uri) {
            return "com.android.externalstorage.documents".equals(uri.getAuthority());
        }
    
        /**
         * @param uri The Uri to check.
         * @return Whether the Uri authority is DownloadsProvider.
         */
        public boolean isDownloadsDocument(Uri uri) {
            return "com.android.providers.downloads.documents".equals(uri.getAuthority());
        }
    
        /**
         * @param uri The Uri to check.
         * @return Whether the Uri authority is MediaProvider.
         */
        public boolean isMediaDocument(Uri uri) {
            return "com.android.providers.media.documents".equals(uri.getAuthority());
        }
    
    }

     

    注意:请记得开启文件读写权限,否则获取到的文件路径为null:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  • 使用okhttp3时忽略所有证书

    1、新建一个SSLSocketClient.java类:

    import java.security.SecureRandom;
    import java.security.cert.X509Certificate;
    
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    
    public class SSLSocketClient {
    
        //获取这个SSLSocketFactory
        public static SSLSocketFactory getSSLSocketFactory() {
            try {
                SSLContext sslContext = SSLContext.getInstance("SSL");
                sslContext.init(null, getTrustManager(), new SecureRandom());
                return sslContext.getSocketFactory();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        //获取TrustManager
        private static TrustManager[] getTrustManager() {
            TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(X509Certificate[] chain, String authType) {
                        }
    
                        @Override
                        public void checkServerTrusted(X509Certificate[] chain, String authType) {
                        }
    
                        @Override
                        public X509Certificate[] getAcceptedIssuers() {
                            return new X509Certificate[]{};
                        }
                    }
            };
            return trustAllCerts;
        }
    
        //获取HostnameVerifier
        public static HostnameVerifier getHostnameVerifier() {
            HostnameVerifier hostnameVerifier = new HostnameVerifier() {
                @Override
                public boolean verify(String s, SSLSession sslSession) {
                    return true;
                }
            };
            return hostnameVerifier;
        }
    
    }

     

    2、使用以下代码来构建okhttp3即可:

    OkHttpClient.Builder mBuilder = new OkHttpClient.Builder();
    mBuilder.sslSocketFactory(SSLSocketClient.getSSLSocketFactory());
    mBuilder.hostnameVerifier(SSLSocketClient.getHostnameVerifier());
    OkHttpClient client = mBuilder.build();

     

  • uni-app离线android打包使用scheme

    hbuilder版本:3.1.12

    在AndroidManifest.xml中对io.dcloud.PandoraEntry添加scheme内容(注意不是io.dcloud.PandoraEntryActivity)

            <activity
                android:name="io.dcloud.PandoraEntry"
                android:configChanges="orientation|keyboardHidden|keyboard|navigation"
                android:label="@string/app_name"
                android:launchMode="singleTask"
                android:hardwareAccelerated="true"
                android:theme="@style/TranslucentTheme"
                android:screenOrientation="portrait"
                android:windowSoftInputMode="adjustResize" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
                <intent-filter>
                    <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.BROWSABLE" />
                    <data android:scheme="xxxxx" />
                </intent-filter>
                <intent-filter>
                    <action android:name="android.intent.action.oppopush" />
                    <category android:name="android.intent.category.DEFAULT" />
                </intent-filter>
            </activity>

    记得把scheme换成正确的。

  • android studio使用发布者证书调试

    修改app.gradle文件:

    android {
        ....................................................
    
        //配置keystore签名
        signingConfigs {
            release {
                storeFile file("./cert/android.keystore")
                storePassword "123456"
                keyAlias "android"
                keyPassword "123456"
            }
        }
    
        buildTypes {
            debug {
                debuggable true
                signingConfig signingConfigs.release
            }
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                signingConfig signingConfigs.release
            }
        }
    }

     

  • Android开发-禁止截图、录屏

    只需要在 Activity 的onCreate() 方法中添加一行代码即可:

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);

    getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);

    添加这行代码后,当截屏的时候,系统会弹出一个Toast提示“禁止屏幕抓取”;当录屏的时候,看似能够正常录制,但是保存后的视频,都是一片黑色,并没有APP的相关界面。

    如果开启禁止录屏后需要在某些场景取消的话,则使用以下语句即可:

    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);