1、使用javah命令获取头文件时,报错“找不到android.graphics.Bitmap”类。
解决方案:在javah命令后面添加 -bootclasspath选项,来指定引导类的路径。这里的引导类为android-sdk/plateforms/android-23/android.jar
2.新浪微博分享不支持arm64Cup架构的手机,,崩溃
使用前检查CPU架构
//获取cpu架构信息线程
private class GetCpuInfo implements Runnable {
@Override
public void run() {
try {
InputStream is = null;
InputStreamReader ir = null;
BufferedReader br = null;
try {
File file = new File("/proc/cpuinfo");
if (!file.exists()) {
return;
}
is = new FileInputStream(file);
ir = new InputStreamReader(is);
br = new BufferedReader(ir);
while (true) {
String line = "";
line = br.readLine();
if (line == null) {
break;
}
if (line.startsWith(KEY_CPU_ARCHITECTRUE)) {
String[] pair = null;
pair = line.split(":");
if (pair.length == 2) {
if (CPU_TYPE_ARM64.equals(pair[1])) {
NearApplication.getInstance().getAppConfigDataEngine().setIsArm64Cpu(true);
}
}
}
Timber.i("line----->" + line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null) {
br.close();
}
if (ir != null) {
ir.close();
}
if (is != null) {
is.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.fragment.startActivityForResult() 可直接在fragment中的onAcitivityResult中接受数据
但是遇到fragment的嵌套时,需要调用fragment.getParentFragment().startActivityForResult() 方法,然后在父fragment中的onActivityResult中接受数据,然后可通过子fragment的引用将数据传递过去。
4.魅族手机开始usb调试后,在mac上不显示连接设备
首先打开终端,输入命令:system_profiler SPUSBDataType,enter之后可以查看连接的各个usb设备的信息,找到供应商ID(Vendor ID),如MX4的Vendor ID为0x2a45;接着在终端输入:echo “0x2a45” > ~/.android/adb_usb.ini,这个就是把你的设备vid添加到adb连接列表;最后重启dab服务,那么在终端依次输入命令:adb kill-server,dab start-server。
5、命令行签名
jarsigner -verbose -keystore /Users/joye/develop/android/workspace/client/near_android/keystore/near_keystore.jks -signedjar signed.apk /Users/joye/Downloads/tap_unsign.apk release
6.运行时找不到主类
原因:机器中同时运行着两个版本的jdk
解决方案:1、ps aux | grep java 查看所有关于java的进程
2、kill -9 3943 指定线程id杀死
7.打开微信和打开微信特定界面
(1)打开微信
ComponentName cmp = new ComponentName(“com.tencent.mm”, “com.tencent.mm.ui.LauncherUI”);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setComponent(cmp);
(2)其他页面的uri
weixin://dl/scan 扫一扫
weixin://dl/feedback 反馈
weixin://dl/moments 朋友圈
weixin://dl/settings 设置
weixin://dl/notifications 消息通知设置
weixin://dl/chat 聊天设置
weixin://dl/general 通用设置
weixin://dl/officialaccounts 公众号
weixin://dl/games 游戏
weixin://dl/help 帮助
weixin://dl/feedback 反馈
weixin://dl/profile 个人信息
weixin://dl/features 功能插件
Intent intent = new Intent();
intent.setData(Uri.parse(“xxxxxx”));
startActivity(intent);
8.监听home键
方法一:保存每一个activity,在onstop方法中,遍历检查每个activity是否都stop了
方法二:复写activity的onUserLeaveHint方法,但是需要在intent上加flag,Intent.FLAG_ACTIVITY_NO_USER_ACTION
方法三:监听Intent.ACTION_CLOSE_SYSTEM_DIALOGS广播,进一步判断广播类型,示例代码如下
class InnerRecevier extends BroadcastReceiver {
final String SYSTEM_DIALOG_REASON_KEY = "reason";
final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
if (reason != null) {
Log.e(TAG, "action:" + action + ",reason:" + reason);
if (mListener != null) {
if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
// home键
mListener.onHomePressed();
} else if (reason
.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
// 长按home键
mListener.onHomeLongPressed();
}
}
}
}
}
}
10、fragment中的onResume 和 onPause方式是activity的方法 通过阅读ViewPager和PageAdapter相关的代码,切换Fragment实际上就是通过设置setUserVisibleHint和setMenuVisibility来实现的,调用这个方法时并不会释放掉Fragment(即不会执行onDestoryView)
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
//相当于Fragment的onResume
} else {
//相当于Fragment的onPause
}
}
11、代码控制字体粗细
在textview中设置画笔的宽度 0 为不加粗(regular) 1为半粗(semibold) 2为粗(bold)
getPaint().setStyle(Paint.Style.FILL_AND_STROKE);
getPaint().setStrokeWidth(1);
12、4.0以上的系统会默认开启硬件加速,在绘制虚线的时候会显示成实线,所以需要手动把当前activity或对应的view设置关闭硬件加速
android:hardwareAccelerated="false"
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
13、监听软键盘的搜索键、确认键
etSearchContent.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId == EditorInfo.IME_ACTION_SEARCH) {
return true;
}
return false;
}
});
14、设置动画使用硬件渲染加速
view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
动画结束后要关闭硬件加速 view.setLayerType(View.LAYER_TYPE_NULL, null);
15、colorPrimaryDark 主调色彩加深 (状态栏背景色) colorPrimary 主调色彩(actionbar背景色, 最近任务title背景色和其他边缘效果)
colorAccent 强调色彩 。应用于框架控制(edittext switch)
16、**5.0以上系统在webview设置cookie时,需要添加额外设置
**
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
cookieManager.setAcceptThirdPartyCookies(webView, true);
}
17、获取软件盘高度并监听软件盘的弹出和关闭
View rootView;
int screenHeight;
ViewTreeObserver.OnGlobalLayoutListener = new ViewTreeOnserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
int keyBoardHeight = screenHeight - (r.bottom - r.top);
if(keyBoardHeight > 0) {
软键盘弹出
} else {
软键盘关闭
}
}
}
注:r为应用显示的区域,不包含状态栏。(r.left , r.top) (r.right , r.bottom) 分别为这个区域左上角和右下角的坐标。所以当状态栏存在的时候,r.top一直是状态栏的高度。当软键盘弹起时,r.bottom为屏幕顶端(包含状态栏)距软键盘顶部的距离
19、canvas 合成图片 渲染文字
/**
* 渲染店铺名称和操作员名称
*
* @param canvas 画布
* @param merchantName 店铺名称
* @param textColor 字体颜色
* @param textSize 字体大小
* @param marginTop 距二维码的距离
* @param optName 操作员名称
* @param lineSpace 行间距
*/
private void drawMerchantNameAndOptName(Canvas canvas, String merchantName, String textColor, int textSize, int marginTop, int bitmapBgWidth, String optName, int lineSpace, int maxWidth) {
TextPaint paint = new TextPaint();
paint.setAntiAlias(true);//抗锯齿
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setColor(Color.parseColor(textColor));//字体颜色
paint.setTextAlign(Paint.Align.CENTER);//从中间开始渲染
paint.setTextSize(textSize);//字号
StaticLayout mTextLayout = new StaticLayout(merchantName, paint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
canvas.save();
int textPositionX = bitmapBgWidth / 2;//文本渲染位置的X坐标
int merchantNamePositionY = marginTop;//商户名称渲染位置的Y坐标
int operatorNamePositionY = marginTop + textSize * 2 + lineSpace;//操作员渲染位置的Y坐标
if(paint.measureText(merchantName) > maxWidth) {
operatorNamePositionY += textSize + lineSpace;
}
canvas.translate(textPositionX, merchantNamePositionY);
mTextLayout.draw(canvas);
canvas.restore();
paint.setTypeface(Typeface.DEFAULT);
canvas.drawText(optName, textPositionX, operatorNamePositionY, paint);
}
//背景图片宽高
qrcodeBgScaledWidth = bitmapBg.getWidth();
qrcodeBgScaledHeight = bitmapBg.getHeight();
Timber.i("width----->" + qrcodeBgScaledWidth);
Timber.i("height----->" + qrcodeBgScaledHeight);
//合成后的图片
bitmapResult = Bitmap.createBitmap(qrcodeBgScaledWidth, qrcodeBgScaledHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmapResult);
canvas.drawBitmap(bitmapBg, 0, 0, null);
canvas.drawBitmap(bitmapQrcode, userQrcodeEntity.getImg_conf().getQr_posx() / scaleRatio, userQrcodeEntity.getImg_conf().getQr_posy() / scaleRatio, null);
//渲染店铺名和操作员名
drawMerchantNameAndOptName(canvas, userQrcodeEntity.getMchnt_name(), userQrcodeEntity.getImg_conf().getFnt_color(), userQrcodeEntity.getImg_conf().getFnt_size() / scaleRatio,
userQrcodeEntity.getImg_conf().getFnt_posy() / scaleRatio, qrcodeBgScaledWidth, userQrcodeEntity.getOpname(), userQrcodeEntity.getImg_conf().getFnt_line_height() / 2, userQrcodeEntity.getFont_width());
//保存画布
canvas.save(Canvas.ALL_SAVE_FLAG);
canvas.restore();
20、使用Service时,解绑连接的时候只能调用unbindService(ServiceConnection);一次,第二此调用会报错:
java.lang.IllegalArgumentException: Service not registered
21、在布局右侧的EditText,包含默认的hint,如何让光标居右
设置属性android:textCursorDrawable = “@null”
22、向相册中插入图片
public static boolean saveImage2Gallery(Context context, String filePath, String fileName) throws IOException {
if (context == null || fileName == null || filePath == null) {
Log.e(TAG, "saveImage2Gallery: context: " + context + ",filePath: " + filePath + ",fileName: " + fileName);
return false;
}
File file = new File(filePath, fileName);
if (!file.exists()) {
throw new FileNotFoundException();
}
if (isPicMedia(fileName)) {
ContentResolver contentResolver = context.getContentResolver();
//向多媒体数据库中插入一条记录
ContentValues values = new ContentValues(3);
values.put(MediaStore.Images.Media.TITLE, "");
values.put(MediaStore.Images.Media.DESCRIPTION, "");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
Uri url = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
//查询新创建记录的id
if (url != null) {
long id = ContentUris.parseId(url);
OutputStream outputStream = null;
FileInputStream fileInputStream = null;
try {
outputStream = contentResolver.openOutputStream(url);
//向uri中写图片数据
fileInputStream = new FileInputStream(new File(filePath, fileName));
byte[] buffer = new byte[1024 * 5];
int len;
while ((len = fileInputStream.read(buffer)) != -1) {
if (outputStream != null) {
outputStream.write(buffer, 0, len);
}
}
} catch (IOException e) {
e.printStackTrace();
throw new IOException();
} finally {
try {
if (outputStream != null) {
outputStream.close();
}
if (fileInputStream != null) {
fileInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//生成缩略图
Bitmap miniThumb = MediaStore.Images.Thumbnails.getThumbnail(contentResolver, id,
MediaStore.Images.Thumbnails.MINI_KIND, null);
//将缩略图插入到数据库
Bitmap microThumb = StoreThumbnail(contentResolver, miniThumb, id, 50F, 50F,
MediaStore.Images.Thumbnails.MICRO_KIND);
FileUtil.deleteFile(new File(filePath, fileName));
return true;
}
return false;
} else {
Log.e(TAG, "saveImage2Gallery: file type error. fileName : " + fileName);
return false;
}
}
23、DatePicker不能重复设置最大日期和最小日期
if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
&& mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
return;
} ———bug here
24、在dimens文件设置浮点数
In dimen.xml
<item name="float" type="dimen" format="float">9.52</item>
Referencing from java
TypedValue typedValue = new TypedValue(); getResources().getValue(R.dimen.my_float_value, typedValue, true); float myFloatValue = typedValue.getFloat();
25、状态栏高度
public static int getStatusBarHeight(Context context) {
Class<?> c = null;
Object obj = null;
java.lang.reflect.Field field = null;
int x = 0;
int statusBarHeight = 0;
try {
c = Class.forName("com.android.internal.R$dimen");
obj = c.newInstance();
field = c.getField("status_bar_height");
x = Integer.parseInt(field.get(obj).toString());
statusBarHeight context.getResources().getDimensionPixelSize(x);
return statusBarHeight;
} catch (Exception e) {
e.printStackTrace();
}
return statusBarHeight;
}
public static int getStatusHeight(Activity activity) {
int stausHeight;
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
stausHeight = frame.top;
return stausHeight;
}
public static int getStatusBarHeight(Context context) {
int result = 0;
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = context.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
26、启用webview的缓存
settings.setAppCacheEnabled(true);
String cachePath = mContext.getCacheDir().getAbsolutePath();
if(Build.VERSION.SDK_INT <= 20) {
//4.4以下需手动设置database路径,方使domstorage生效
cachePath += "/database";
settings.setDatabasePath(cachePath);
}
Log.d(TAG, "setWebViewSetting: cachePath--->"+cachePath);
settings.setAppCachePath(cachePath);
settings.setAllowFileAccess(true);
27、adb shell dump sys activity 查看Activity栈
28、减法、除法不精确的问题
使用BitDecimal进行加减乘除
29、
textview.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG |Paint.ANTI_ALIAS_FLAG);加上这个属性,字体更清晰一些