长期补充,我只是大自然的搬运工
1.获取手机的宽度和高度
WindowManager wm = this.getWindowManager();int width = wm.getDefaultDisplay().getWidth();int height = wm.getDefaultDisplay().getHeight();
2.popupWindow布局居中显示
popup.setHeight(LayoutParams.WRAP_CONTENT); popup.setWidth(width*3/4); //为手机的宽度(上面的width)popup.showAtLocation(listView, Gravity.CENTER,0,0);//s
3.判断手机是否安装某第三方app
想要判断是否安装第三方app,就必须知道包名,包名的话,只能去反编译了。从AndroidManifest 去找到对应的package属性。
好了,言归正传,有了包名,只要遍历这个手机中所有的应用的包名就可以了,网上找了一个可用的方法,我觉得写的还是挺详细的
/** * 检查手机上是否安装了指定的软件 * @param context * @param packageName:应用包名 如 com.example.test * @return */ private boolean isAvilible(Context context, String packageName){ //获取packagemanager final PackageManager packageManager = context.getPackageManager(); //获取所有已安装程序的包信息 List<PackageInfo> packageInfos = packageManager.getInstalledPackages(0); //用于存储所有已安装程序的包名 List<String> packageNames = new ArrayList<String>(); //从pinfo中将包名字逐一取出,压入pName list中 if(packageInfos != null){ for(int i = 0; i < packageInfos.size(); i++){ String packName = packageInfos.get(i).packageName; packageNames.add(packName); } } //判断packageNames中是否有目标程序的包名,有TRUE,没有FALSE return packageNames.contains(packageName); }
4.关于拍照的回调返回的数据的问题
在onActivityResult中,从返回的Intent中,获得的Uri uri = data.getData();uri在4.3—->4.4系统的时候产生了不同在4.4一下,可以直接使用,但是在4.4以后,返回的是content://。。。。,会出现无法加载此图片。
private void handleData(Intent data) { Uri uri = data.getData(); // 4.4以后新特征 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { String url = getPath(PersonalDataActivity.this, uri); uri = Uri.fromFile(new File(url)); handleData(uri); } else { // 4.4以下 handleData(uri); }}
通过判断当然系统的版本进行不同的处理,主要是getPath这个方法。网上也有这个方法,测试可用
// 4.4新特征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]; } // TODO handle non-primary volumes } // 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; } 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 the remote address if (isGooglePhotosUri(uri)) return uri.getLastPathSegment(); 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 static 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 index = cursor.getColumnIndexOrThrow(column); return cursor.getString(index); } } finally { if (cursor != null) cursor.close(); } return null;}/** * @param uri * The Uri to check. * @return Whether the Uri authority is ExternalStorageProvider. */public static 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 static 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 static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri .getAuthority());}/** * @param uri * The Uri to check. * @return Whether the Uri authority is Google Photos. */public static boolean isGooglePhotosUri(Uri uri) { return "com.google.android.apps.photos.content".equals(uri .getAuthority());}
开发的时候需要把自己开发时候的包改为4.4.因为DocumentsContract 是在4.4包中独有的类。
4.3的开发包是找不到这个类的,会报红。
5.把网络图片转化为存在本地
先将流转化为bitmap对象
map = BitmapFactory.decodeStream(inStream);
然后再讲bitmap存在本地。
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));map .compress(Bitmap.CompressFormat.JPEG, 80, bos);
其中的file可以调用这个File(String dirPath, String name) ,目录加名字来构造
6.本地保存图片之后需要刷新相册
//相册扫描图片Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);Uri uri = Uri.fromFile(new File(mFilePath));intent.setData(uri);sendBroadcast(intent);
7.需要判断第三方应用是否安装(代码在上)
如果未安装,跳转下载,调到浏览器下载
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("下载网址"));mContext.startActivity(intent);
如果安装了,直接打开app
PackageManager packageManager = mContext.getPackageManager(); Intent intent1 = packageManager.getLaunchIntentForPackage("包名"); mContext.startActivity(intent1);
8.拨打电话
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"+ "电话号码"));startActivity(intent);
9.跳转到打电话的页面
Intent intent = new Intent(Intent.ACTION_DIAL);intent.setData(Uri.parse("tel:" + telephone));context.startActivity(intent);
10.复制到剪切板
public static void copy2Clipboard(Context context,String msg){ ClipboardManager cm = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); // 将文本内容放到系统剪贴板里。 ClipData clip = ClipData.newPlainText("simple text", msg); // Set the clipboard's primary clip. cm.setPrimaryClip(clip); Toast.makeText(context, "复制成功", Toast.LENGTH_LONG).show();}
11.有EditText时候进入界面默认弹出输入框
防止有EditText时候进入界面直接弹出输入框,不友好
可以在EditText前面放置一个看不到的LinearLayout
<LinearLayout android:focusable="true" android:focusableInTouchMode="true" android:layout_width="0px" android:layout_height="0px"/>
或者在他的父布局中加入
android:focusable="true" android:focusableInTouchMode="true"
即可
12.关于WebView的使用用到的问题
1.加载完显示空白页:
@Override public boolean shouldOverrideUrlLoading(WebView view, String url) { CommUtil.logD(TAG, "shouldOverrideUrlLoading, url:" + url); return false; }
返回false 就好了
2.webview 中加载页面的对话框
如果需要弹出网页的对话框之类的,需要设置如下
mWebView.setWebChromeClient(new WebChromeClient(){ @Override public boolean onJsAlert(WebView view, String url, String message, JsResult result) { return super.onJsAlert(view, url, message, result); } });
13.android 6.0的权限的问题
android 6.0的手机就算manifest文件中设置了存储权限,app运行时候还是需要手动申请,否则在app里面创建文件夹会失败。
需要 调用 showPremissDialogIfNeccessary 就好了
private static final int REQUEST_CODE_FOR_WRITE_PERMISSON = 1;public void showPremissDialogIfNeccessary(){ //6.0 权限的手机需要打开权限 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE); if(hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED){ requestPermissions(new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE }, REQUEST_CODE_FOR_WRITE_PERMISSON); return; } }}@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if(requestCode == REQUEST_CODE_FOR_WRITE_PERMISSON){ if(permissions[0].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE) && grantResults[0] == PackageManager.PERMISSION_GRANTED){ //同意就情况 }else{ Toast.makeText(mContext, R.string.request_write_pression_failed, Toast.LENGTH_SHORT).show(); } }}
由于上述的方法中是在sdk 为 6.0 的方法存在的,这里我们可以使用v4扩展包来帮助我们实现权限判断,
ContextCompat.checkSelfPermission()
ActivityCompat.requestPermissions()
ActivityCompat.OnRequestPermissionsResultCallback
ActivityCompat.shouldShowRequestPermissionRationale()
首先这个activity 要实现 ActivityCompat.OnRequestPermissionsResultCallback方法,这样就必须重写onRequestPermissionsResult方法。
private static final int REQUEST_CODE_FOR_WRITE_PERMISSON = 1;public void showPremissDialogIfNeccessary(){ //大于6.0 权限的手机需要打开权限 if(Build.VERSION.SDK_INT >= 23){ int hasWriteContactsPermission = ContextCompat.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE); if(hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED){ ActivityCompat.requestPermissions(new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE }, REQUEST_CODE_FOR_WRITE_PERMISSON); return; } }}@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if(requestCode == REQUEST_CODE_FOR_WRITE_PERMISSON){ if(permissions[0].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE) && grantResults[0] == PackageManager.PERMISSION_GRANTED){ //同意 }else{ Toast.makeText(mContext, "获取存储权限失败"), Toast.LENGTH_SHORT).show(); } }}