长期补充,我只是大自然的搬运工=。=
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
项目中遇到,需要判断支付宝是否安装,弹出提示。像判断微信是否安装,自己的jar包中会有isWXAppInstalled的方法。但是支付宝貌似没找到
想要判断是否安装第三方app,就必须知道包名,包名的话,只能去反编译了。从AndroidManifest 去找到对应的package属性。
对了,突然想到,开发中,如果突然想改项目的包名,在Android Tools 中 rename Application 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);
拨打电话
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"+ "电话号码"));
startActivity(intent);
跳转到打电话的页面
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:" + telephone));
context.startActivity(intent);
复制到剪切板
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();
}
防止有EditText时候进入界面直接弹出输入框,不友好
可以在EditText前面放置一个看不到的LinearLayout
<LinearLayout
android:focusable="true"
android:focusableInTouchMode="true"
android:layout_width="0px"
android:layout_height="0px"/>
或者在他的父布局中加入
android:focusable="true"
android:focusableInTouchMode="true"
即可
关于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);
}
});
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;
}
}
}
@Override
public 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();
}
}
}
关于Listview 的divider的设置问题,如果数据item最后一个不需要现实divider的样式(分割线),需要将Listview 设置成wrap_content就好了(recyclerview不知道,有兴趣的朋友可以试一下)
由于使用了markDown编辑器,该博客不维护,请移步 Android开发过程中遇到的问题(长期补充)