最近总结的android疑惑(三)

android删除多语言:

./mediatek/config/common/ProjectConfig.mk中找到 PRODUCT_LOCALES= 对该行进行修改


修改默认时区 


修改frameworks/base/core/java/com/android/internal/os/RunTimeInit.java文件
commonInit方法
      

 TimezoneGetter.setInstance(new TimezoneGetter() {
           @Override

           public String getId() {
           Stringzoneinfo = SystemProperties.get("persist.sys.timezone");
           if(zoneinfo==null||zoneinfo.length()==0)
           {
                    SystemProperties.set("persist.sys.timezone","America/Santiago");//设置时区     America/Santiago字符串可以在Time_zones_by_country.xml(frameworks\base\core\res\res\xml)文件中查找
           }
               return SystemProperties.get("persist.sys.timezone");
            }
        });

获得手机屏幕的宽度和高度:

 public static int getScreenWidth(Context context)  
    {  
        WindowManager wm = (WindowManager) context  
                .getSystemService(Context.WINDOW_SERVICE);  
        DisplayMetrics outMetrics = new DisplayMetrics();  
        wm.getDefaultDisplay().getMetrics(outMetrics);  
        return outMetrics.widthPixels;  
    }


dx,dp,px之间的单位转换:

/** 
     * dp转px 
     *  
     * @param context 
     * @param val 
     * @return 
     */  
    public static int dp2px(Context context, float dpVal)  
    {  
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,  
                dpVal, context.getResources().getDisplayMetrics());  
    }  

    /** 
     * sp转px 
     *  
     * @param context 
     * @param val 
     * @return 
     */  
    public static int sp2px(Context context, float spVal)  
    {  
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,  
                spVal, context.getResources().getDisplayMetrics());  
    }  


 /** 
     * px转dp 
     *  
     * @param context 
     * @param pxVal 
     * @return 
     */  
    public static float px2dp(Context context, float pxVal)  
    {  
        final float scale = context.getResources().getDisplayMetrics().density;  
        return (pxVal / scale);  
    }  

/** 
     * px转sp 
     *  
     * @param fontScale 
     * @param pxVal 
     * @return 
     */  
    public static float px2sp(Context context, float pxVal)  
    {  
        return (pxVal / context.getResources().getDisplayMetrics().scaledDensity);  
    }  

         如果需要apkA和apkB共享一个数据库的话,则需要将其android:sharedUserId设为相同就可以了,例如apkA中的manifest.xml文件如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.android.demo.a1"
    android:sharedUserId="com.c">

  注意,这是apkB也需要将android:sharedUserId的值设置为:"com.c",此时才可以访问apkA中的数据库:

此时可以通过如下方式得到一个context,通过该context我们就可以访问apkA中的数据了:

 Context friendContext = this.createPackageContext(
                    "com.android.demo.a1",
                    Context.CONTEXT_IGNORE_SECURITY);



        android判断是否是横竖屏:

1.Display display = getWindowManager().getDefaultDisplay();
boolean isPortrait = display.getWidth() < display.getHeight();

2.DisplayMetrics dm = context.getApplicationContext().getResources().getDisplayMetrics();
Boolean isPortrait = dm.widthPixels < dm.heightPixels;

3.boolean isPortrait = false ;
if(android.content.res.Configuration.orientation == android.content.res.Configuration.ORIENTATION_PORTRAIT)
{
    isPortrait = true ;
}
else if(android.content.res.Configuration.orientation == android.content.res.Configuration.ORIENTATION_LANDSCAPE)
{
    isPortrait = false ;
}
注意第三种方式,需要在manifest.xml中的application标签中添加如下配置:
//在Application标签中加入
android:configChanges="orientation"


          利用android自带的zipalign来优化我们的程序:

         zipalign -v 4 source.apk destination.apk


          简单利用monkey来测试程序性能:monkey -p com.android.camera -v 500   顾名思义com.android.camera 是我们需要测试的应用程序的包名

   

         android实现简单的倒计时效果:

         在android中为我们提供了这样的一个类CountDownTimer,可以来实现简单的倒计时效果:

class MyCount extends CountDownTimer {     
		public MyCount(long millisInFuture, long countDownInterval) {     
			super(millisInFuture, countDownInterval);     
		}     
		@Override     
		public void onFinish() {     
			tv.setText("finish");        
		}     
		@Override     

		public void onTick(long millisUntilFinished) {     
			tv.setText("请等待30秒(" + millisUntilFinished / 1000 + ")...");     
		}    
	} 

        然后,在oncreate方法中:

                tv = (TextView) findViewById(R.id.id_text);
		final MyCount mc = new MyCount(30000,1000);
		mc.start();



android实现抖动效果:
第一步:准备两个动画效果的XML文件,加入到 res/anim/目录下:
Shake.xml文件:

<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0"
    android:toXDelta="10"
    android:duration="1000"
    android:interpolator="@anim/cycle_7" />

cycle_7.xml文件:
<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:cycles="7" />
第二步: //代码使用动画效果:
      
  Animation shake = AnimationUtils.loadAnimation(this, R.anim.shake);//加载动画资源文件
        findViewById(R.id.xxxx).startAnimation(shake); //给组件播放动画效果



            scrollview滚动到底部:

下面我们看一下这个函数:
scrollView.fullScroll(ScrollView.FOCUS_DOWN);滚动到底部
scrollView.fullScroll(ScrollView.FOCUS_UP);滚动到顶部

需要注意的是,该方法不能直接被调用
因为Android很多函数都是基于消息队列来同步,所以需要一部操作,
addView完之后,不等于马上就会显示,而是在队列中等待处理,虽然很快,但是如果立即调用fullScroll, view可能还没有显示出来,所以会失败
应该通过handler在新线程中更新
    handler.post(new Runnable() {  
        @Override  
        public void run() {  
            scrollView.fullScroll(ScrollView.FOCUS_DOWN);  
        }  
    });  


                


             android流量监控:

public void getAppTrafficList(){  
        //获取所有的安装在手机上的应用软件的信息,并且获取这些软件里面的权限信息  
        PackageManager pm=getPackageManager();//获取系统应用包管理  
        //获取每个包内的androidmanifest.xml信息,它的权限等等  
        List<PackageInfo> pinfos=pm.getInstalledPackages  
                (PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_PERMISSIONS);  
        //遍历每个应用包信息  
        for(PackageInfo info:pinfos){  
            //请求每个程序包对应的androidManifest.xml里面的权限  
            String[] premissions=info.requestedPermissions;  
            if(premissions!=null && premissions.length>0){  
                //找出需要网络服务的应用程序  
                for(String premission : premissions){  
                    if("android.permission.INTERNET".equals(premission)){  
                        //获取每个应用程序在操作系统内的进程id  
                        int uId=info.applicationInfo.uid;  
                        //如果返回-1,代表不支持使用该方法,注意必须是2.2以上的  
                        long rx=TrafficStats.getUidRxBytes(uId);  
                        //如果返回-1,代表不支持使用该方法,注意必须是2.2以上的  
                        long tx=TrafficStats.getUidTxBytes(uId);  
                        if(rx<0 || tx<0){  
                            continue;  
                        }else{  
                            Toast.makeText(this, info.applicationInfo.loadLabel(pm)+"消耗的流量--"+  
                        Formatter.formatFileSize(this, rx+tx), Toast.LENGTH_SHORT);  
                        }  
                    }  
                }  
            }  
        }  
    }  
另外还有其他的一些方法:

static long getMobileRxBytes()//获取通过Mobile连接收到的字节总数,但不包含WiFi
static long getMobileRxPackets()//获取Mobile连接收到的数据包总数
static long getMobileTxBytes()//Mobile发送的总字节数
static long getMobileTxPackets()//Mobile发送的总数据包数
static long getTotalRxBytes()//获取总的接受字节数,包含Mobile和WiFi等
static long getTotalRxPackets()//总的接受数据包数,包含Mobile和WiFi等
static long getTotalTxBytes()//总的发送字节数,包含Mobile和WiFi等
static long getTotalTxPackets()//发送的总数据包数,包含Mobile和WiFi等
static long getUidRxBytes(int uid)//获取某个网络UID的接受字节数
static long getUidTxBytes(int uid) //获取某个网络UID的发送字节数



设置软件盘自动弹出:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);



             android格式化字符串:

             比如,我在string.xml中定义了这样一条字符串:

             <string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
            代码中需要这样写:

String tempText = getResources().getString(R.string.welcome_messages);
        TextView text = (TextView) findViewById(R.id.id_text);
        text.setText(tempText.format(tempText,"haha",2));



关于audioManager中的几种获取焦点的不同:
1.AUDIOFOCUS_GAIN    这种方式会获得焦点,可是在我们放弃焦点的时候,之前的那个音频不能自动播放
2. AudioManager.AUDIOFOCUS_GAIN_TRANSIENT    这种方式会获得焦点,当放弃焦点的时候,之前的音频同样会继续播放,可是如果会暂时取消之前音频的notification
3.AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE  ,AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
这两种方式不会取消notification,可是对于FM是不起作用的。



          关于adb logcat的常见用法:


adb logcat | grep MyApp
adb logcat | grep -i myapp #忽略大小写。

要过滤 tag 为 MyApp 和 MyActivity 的输出:
adb logcat | grep -v "^..MyApp\|^..MyActivity"

有时需要分析 log 文件,过滤 log 文件还是使用 grep。例如 log 文件为 myapp.log,要匹配 tag 为 MyApp 和 MyActivity 的输出,然后输出到 newmyapp.log:
cat myapp.log | grep "^..MyApp\|^..MyActivity" > newmyapp.log


使用android:background="@drawable/bg"属性设置背景,android:cacheColorHint="@android:color/transparent"设置item背景为透明,解决在滑动item出现黑色背景的问题



使用Martix(android.graphics.Matrix)类中的postScale()方法结合Bitmap来实现缩放图片的功能

Bitmap bmp = BitmapFactory.decodeResource(getResource(),R.drawalbe.icon1)
int bmpwidth = bmp.getWidth();
int bmpheight = bmp.getHeight();
Matrix matrix = new Matrix();
matrix.postScale(width,height);
Bitmap bm = Bitmap.createBitmap(bmp,0,0,bmpwidth,bmpheight ,matrix,true);
imageView.setImageBitmap(bm);


                requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题栏
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);// 设置全屏
		// 设置横屏显示
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
		// 选择支持半透明模式,在有surfaceview的activity中使用。
		getWindow().setFormat(PixelFormat.TRANSLUCENT);



从Android 2.2开始系统新增了一个缩略图ThumbnailUtils类,位于framework的android.media.ThumbnailUtils位置,可以帮助我们从mediaprovider中获取系统中的视频或图片文件的缩略图,该类提供了三种静态方法可以直接调用获取。
1.
static Bitmap createVideoThumbnail(String filePath, int kind) //获取视频文件的缩略图,第一个参数为视频文件的位置,比如/sdcard/android123.3gp,而第二个参数可以为MINI_KIND或 MICRO_KIND最终和分辨率有关
2.
static Bitmap extractThumbnail(Bitmap source, int width, int height, int options) //直接对Bitmap进行缩略操作,最后一个参数定义为OPTIONS_RECYCLE_INPUT ,来回收资源
3.
static Bitmap extractThumbnail(Bitmap source, int width, int height) // 这个和上面的方法一样,无options选项



activity切换动画

public void onClick(View v) {
                Intent intent = new Intent(ActivityAnim.this,ActivityTwo.class);
                startActivity(intent);                
                overridePendingTransition(R.anim.act_enter,R.anim.act_exit);                
  }
overridePendingTransition(int ,int)函数,第一个参数为activity显示动画,第二个参数为退出动画,两个动画的xml文件存放在anim文件夹下



popupwindow切换动画
popwindow通过setAnimationStyle(int animationStyle)函数来设置动画效果
android:windowEnterAnimation表示进入窗口动画
android:windowExitAnimation表示窗口退出动画
     在res/values/style.xml代码:
<style name="PopupAnimation" parent="android:Animation" mce_bogus="1">        
        <item name="android:windowEnterAnimation">@anim/popup_enter</item>    
        <item name="android:windowExitAnimation">@anim/popup_exit</item>    
</style>    




 /***//**
     * 图片去色,返回灰度图片
     * @param bmpOriginal 传入的图片
     * @return 去色后的图片
     */
    public static Bitmap toGrayscale(Bitmap bmpOriginal) {
        int width, height;
        height = bmpOriginal.getHeight();
        width = bmpOriginal.getWidth();    

        Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        Canvas c = new Canvas(bmpGrayscale);
        Paint paint = new Paint();
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);
        ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
        paint.setColorFilter(f);
        c.drawBitmap(bmpOriginal, 0, 0, paint);
        return bmpGrayscale;
    }


/***//**
     * 把图片变成圆角
     * @param bitmap 需要修改的图片
     * @param pixels 圆角的弧度
     * @return 圆角图片
     */
    public static Bitmap toRoundCorner(Bitmap bitmap, int pixels) {

        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
                .getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        final float roundPx = pixels;

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);

        return output;
    }



        设置背景样式:

 <style name="TransparentStyleBottom">  
            <item name="android:windowIsTranslucent">true</item><!--半透明            -->   
            <item name="android:windowNoTitle">true</item><!--无标题-->   
            <item name="android:windowBackground">@android :color/transparent</item><!--背景透明          -->   
            <item name="android:backgroundDimEnabled">true</item><!--模糊-->   
    </style> 


android TextView图文混写 嵌入表情

    private void setImageText()  
        {  
            //根据ID获取图像的Bitmap对象  
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);  
            //创建imageSpan对象  
            ImageSpan imageSpan = new ImageSpan(this, bitmap);  
            //创建一个SpannableString对imageSpan进行封装  
            SpannableString spannableString = new SpannableString("icon哇咔咔");  
            //用ImageSpan对象替换icon  
            spannableString.setSpan(imageSpan, 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
            tv_hello.setText(spannableString);  
        }  




在Android加载到内存的Bitmap是不允许修改的,只能够在其副本上修改和作画。那么如何创建一个原图的副本呢?
需要以下这些步骤:
    ①准备一个和原图宽高及配置完全一样的白纸
    ②白纸放在画布上
    ③准备一支笔
    ④准备一个矩阵 
ImageView srcImageView = (ImageView) findViewById(R.id.iv_src);
ImageView copyImageView = (ImageView) findViewById(R.id.iv_copy);
// 原图
Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/meinv.jpg");
srcImageView.setImageBitmap(srcBitmap);
// 拷贝
// 1. 准备一个和原图宽高完全一样的白纸
Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
// 2. 把白纸放在画布上
Canvas canvas = new Canvas(copyBitmap);
// 3. 准备一支笔
Paint paint = new Paint();
// 4. 准备一个矩阵
Matrix matrix = new Matrix();
// 使用指定的矩阵绘图
canvas.drawBitmap(srcBitmap, matrix, paint);
copyImageView.setImageBitmap(copyBitmap);






pm命令的学习:
首先进入adb shell
pm list package 查看所有已经安装的程序的包名
pm list package -f   查看已经安装的程序,的apk所在的路径
pm list permissions 查看已知的所有权限
pm list permission-group  查看已知的所有的权限组
pm path com.TDiJoy.fane 列出指定包名的apk存档文件
pm install /data/3dijoy_fane.apk 安装apk
pm uninstall 包名  卸载apk




 android使用自定义的第三方字体库:
// 将字体文件保存在assets/fonts/目录下,www.linuxidc.com创建Typeface对象
Typeface typeFace = Typeface.createFromAsset(getAssets(),"fonts/DroidSansThai.ttf");
// 应用字体
textView.setTypeface(typeFace);


设置popupwindow的底部弹出:

PopupWindow window = new PopupWindow(MainActivity.this);
window.setContentView(view);
window.setTouchable(true);
window.setOutsideTouchable(true);
window.setWidth(LayoutParams.MATCH_PARENT);
window.setHeight(180);
window.setAnimationStyle(R.style.popwindow);
window.showAtLocation(button, Gravity.BOTTOM,0,0);
mPopupWindow.update(); //注意在动画结束的时候需要调用update()方法,更新


// 获取在当前窗口内的绝对坐标
View.getLocationInWindow()
// 获取在整个屏幕内的绝对坐标,注意这个值是要从屏幕顶端算起,也就是包括了通知栏的高度。
View.getLocationOnScreen()



android获取id的另一种方式:
    

    Resources resource = this.getResources();  
    String pkgName = this.getPackageName();  
    setContentView(resource.getIdentifier("main", "layout", pkgName));  
    akBtnId = resource.getIdentifier("btn_initAK", "id", pkgName);  
    Button initWithApiKey = (Button) findViewById(akBtnId); 


android属性动画简单总结:

ObjectAnimator:
根据属性值设置不同的属性动画
 

ObjectAnimator.ofFloat(view, property, from , to)
                        .setDuration(500)
                        .start();

通过ObjectAnimator实现多动画同时操作
 //这里将属性设为ocean是以为Android不认识这个属性,所以不会做任何改变,而我们要用from和to,所以就这样设定。
    ObjectAnimator anim = ObjectAnimator.ofFloat(view, "ocean", from , to);//这里的参数可以设置三个,就是先小后大了。
    anim.setDuration(2000);
    anim.start();
    anim.addUpdateListener(new AnimatorUpdateListener() {

        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            float x = (Float) animation.getAnimatedValue();
            view.setAlpha(x);
            view.setScaleX(x);
            view.setScaleY(x);
        }
    });

使用PropertyValuesHolder来实现ObjectAnimator的多属性动画
 

ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view,
                PropertyValuesHolder.ofFloat("scaleX",1.0f, 0.0f,1.0f),//这里的参数设置三个,先小后大。
                PropertyValuesHolder.ofFloat("scaleY", 1.0f,0.0f,1.0f),
                PropertyValuesHolder.ofFloat("alpha", 1.0f,0.0f,1.0f)
        ).setDuration(2000);
        animator.setInterpolator(new LinearInterpolator());
        animator.start();


ValueAnimator的使用 
ValueAnimator anim = ValueAnimator.ofFloat(from,to);
        anim.setTarget(view);
        anim.setDuration(2000);
        anim.setInterpolator(new AccelerateInterpolator());
        anim.start();
        anim.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                if (orientation.equals("y")) {
                    view.setTranslationY((Float)animation.getAnimatedValue());
                }else{
                    view.setTranslationX((Float)animation.getAnimatedValue());
                }
            }
        });

AnimatorSet的使用

同时执行
 
ObjectAnimator obj1 = ObjectAnimator.ofFloat(view, "scaleX", 1.0f,0.5f,1.0f);
        ObjectAnimator obj2 = ObjectAnimator.ofFloat(view, "scaleY", 1.0f,0.5f,1.0f);
        ObjectAnimator obj3 = ObjectAnimator.ofFloat(view, "rotationX", 0.0f,180.0f,0.0f);
        AnimatorSet set = new AnimatorSet();
        set.setDuration(2000);
        set.setInterpolator(new LinearInterpolator());
        set.playTogether(obj1,obj2,obj3);
        set.start();

分步执行:
ObjectAnimator obj1 = ObjectAnimator.ofFloat(view, "scaleX", 1.0f,0.5f,1.0f);
        ObjectAnimator obj2 = ObjectAnimator.ofFloat(view, "scaleY", 1.0f,0.5f,1.0f);
        ObjectAnimator obj3 = ObjectAnimator.ofFloat(view, "rotationX", 0.0f,180.0f,0.0f);
        AnimatorSet set = new AnimatorSet();
        set.setDuration(2000);
        set.setInterpolator(new LinearInterpolator());
        set.play(obj1).after(obj2);
        set.play(obj2).after(obj3);
        set.start();

AnimatorInflater是属性动画的另一种加载方式
Animator animator = AnimatorInflater.loadAnimator(context, id);
        animator.setTarget(view);
        animator.setDuration(2000);
        animator.setInterpolator(new LinearInterpolator());
        animator.start();





android图片处理:

                Bitmap bitmap = null;
		bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.testback);
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		
		Bitmap tempBit = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
		
		int pixColor = 0;
		int pixR = 0;
		int pixG = 0;
		int pixB = 0;
		int newR = 0;
		int newG = 0;
		int newB = 0;
		
		int[] pixels = new int[width * height];
		bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
		for (int i = 0; i < height; i++) {
			for (int j = 0; j < width; j++) {
				 pixColor = pixels[width * i + j];  
		            pixR = Color.red(pixColor);  
		            pixG = Color.green(pixColor);  
		            pixB = Color.blue(pixColor);  
		            newR = (int) (0.393 * pixR + 0.769 * pixG + 0.189 * pixB);  
		            newG = (int) (0.349 * pixR + 0.686 * pixG + 0.168 * pixB);  
		            newB = (int) (0.272 * pixR + 0.534 * pixG + 0.131 * pixB);  
		            int newColor = Color.argb(255, newR > 255 ? 255 : newR, newG > 255 ? 255 : newG, newB > 255 ? 255 : newB);  
		            pixels[width * i + j] = newColor;  
			}
		}
		tempBit.setPixels(pixels, 0, width, 0, 0, width, height);
		
		ImageView imageView = (ImageView) findViewById(R.id.imageView1);
		imageView.setImageBitmap(tempBit);




git学习:

git config --global user.name "yourname"
git config --global user.email "[email protected]"

git log --pretty=oneline

将当前的版本回退到上一个版本:
git reset --hard HEAD^

回到某一个版本:
git reset --hard 需要回退的版本的序列号
通过命令:git reflog可以查看提交记录的commit id

查看分支:git branch
创建分支:git branch 分支名称
切换分支: git checkout 分支名称
创建+切换分支: git checkout -b 分支名称
合并某个分支到当前分支: git merge 分支名称
删除分支: git branch -d 分支名称

让git显示颜色,会让命令输入起来更加的醒目:
git config --global color.ui true



你可能感兴趣的:(android)