一、ListView优化图片错位问题
setTag 将图片的url设置上
在放图片的时候先取Tag 判断俩个是否相等 相等再去设置
二、edtiText加载图片
SpannableString 与String的区别是可以设置样式如果组件不支持就成为String了,
span()是设置样式的
源码
SpannableString builder = new SpannableString(et.getText()
.toString()+"");
ImageSpan img = new ImageSpan(MainActivity.this,
R.drawable.ic_launcher);
builder.setSpan(img, et.getText().toString().length(), et
.getText().toString().length() + 1,
Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
et.setText(builder);
三、Gson解析
也是像json一层一层来解析,与json不同的是gson封装的是对象
四、缓存技术
softReference weakReference lruCache
第一次是从网络下载的根据uri保存到缓存并保存到sd卡(这里需要获取看有没有) 显示的时候 先从缓存(lruCache)中获取如果有就显示 没有就
从sd卡获取
如何有就显示并添加到缓存里(lruCache) 没有在从网络获取在添加到缓存和集合中
五、断点续传
RandomAccessFile 有指针 通过指针获取位置
FileOutputStream 构造方法两个参数的 true代表将数据追加到文件末尾
过程 从网络上获取用RandomAccessFile 并用FileOutputStream 写入文件 写入过程并将RandomAccessFile.getFilePointer()和文件名 写入数据
库 如何网络断了 就根据
文件名取文件的pointer值 通过RandomAccessFile.seek();设置从哪开始
异常: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
android 中数据库处理,特别是使用cursor时,注意初始位置,好像是从下标为-1的地方开始的,也就是说一次查询中,返回给cursor查询结
果时,不能够马上从cursor中提取值。
cursor.moveToFirst()
六、Parcelable
写一个类 实现 parcelable接口 写要保存数据的字段 setget方法 在
protected MyParcelable(Parcel in) {
mData = in.readInt();
time=in.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mData);
dest.writeString(time);
}
就OK了
七、 faceDetor 人脸识别技术
注意的有图片
八、蓝牙
蓝牙是API level 5 就有的一个技术 虽然现在这个技术很少使用 但是我们还是要学一学的
wifi 技术是一个崭新的时代 他替代了蓝牙 (这是我个人认为) 我们要向新时代去努力!!!
客户端
private static final UUID MY_UUID_SECURE = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66"); //安全的
private static final UUID MY_UUID_INSECURE = UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66"); //不安全的
首先我们先将蓝牙的权限加上
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
要想扫描到蓝牙 蓝牙必须是可见的
通过intent 启动 BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE 就可以将蓝牙可见
蓝牙可见了我们就获取获取蓝牙的适配器
BluetoothAdapter.getDefaultAdapter();
在通过蓝牙适配器的startDiscovery() 方法开始扫描周边可见的蓝牙 通过绑定广播过滤 new IntentFilter(BluetoothDevice.ACTION_FOUND)
//代表找到了蓝牙
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); //获取到蓝牙的驱动 根据驱动来获取 地址及其相
关信息
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
}
也可以通过getBondedDevices() 获取驱动 这个方法返回的是一个集合
要想连接服务器 我们通过驱动获取地址 通过getRemoteDevice(address); 获取到指定蓝牙的驱动
在通过这个驱动的 createInsecureRfcommSocketToServiceRecord(MY_UUID_INSECURE); //这个是不安全的是不需要验证的
createRfcommSocketToServiceRecord(MY_UUID_SECURE); //这个是安全的需要验证的
他俩都会返回一个BluetoothSocket 对象 我们通过他调用 connect() 和服务器端连接
如果连接成功 就可以通过他获取input 或 output 流 来写去和读取
服务器端
我们通过 BlueAdapter的 listenUsingInsecureRfcommWithServiceRecord(NAME_INSECURE,MY_UUID_INSECURE);//不安全的 这俩个方法 是与客
户端的俩个方法对应的
listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE); //安全的
他们会返回一个BluetoothServerSocket 对象 在通过这个对象的 accpet()方法(注意这个方法是会阻塞主线程的 我们要将他放到子线程 )
返回一个BluetoothSocket 对象
在通过socket对象 获取input或output流来传输数据
蓝牙讲解完毕,有什么不对还请您指点!!!
九、Wifi
权限:
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <!-- 允许程序改变网络链接状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><!-- 允许程序访问访问WIFI网络状态信息 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /><!-- 允许程序改变WIFI链接状态 -->
<uses-permission android:name="android.permission.INTERNET" />
先获取WifiManager对象
WifiManager manager=getSystemService(WifiManager.WIFI_SERVICE);
通过setWifiEnabled()方法设置wifi打开与关闭
通过调用 startScan()扫描周围的热点
通过绑定广播 过滤WifiManager.SCAN_RESULTS_AVAILABLE_ACTION
通过manager.getScanResults();获取扫描的热点
获取要连接的热点的capabilities和SSID
capabilities是一种加密模式 如WPA2 WPA WEP
首先调用addNetwork(); 会有个返回值 根据返回值判断 -1代表失败 这里需要一个WifiConfiguration对象
调用 manager.enableNetwork(netId, true); 连接wifi
public WifiConfiguration generateWifiConfiguration(AuthenticationType type,
String ssid, String password) {
WifiConfiguration config = new WifiConfiguration();
config.SSID = String.format("\"%s\"", ssid);
switch (type) {
case TYPE_NONE: {
config.wepKeys[0] = "\"\"";
config.wepTxKeyIndex = 0;
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
break;
}
case TYPE_WEP: {
config.wepKeys[0] = String.format("\"%s\"", password);
config.wepTxKeyIndex = 0;
config.allowedAuthAlgorithms
.set(WifiConfiguration.AuthAlgorithm.SHARED);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
config.allowedGroupCiphers
.set(WifiConfiguration.GroupCipher.WEP104);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
break;
}
case TYPE_WPA: {
config.preSharedKey = String.format("\"%s\"", password);
config.allowedAuthAlgorithms
.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.CCMP);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.NONE);
config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
break;
}
case TYPE_WPA2: {
config.preSharedKey = String.format("\"%s\"", password);
config.allowedAuthAlgorithms
.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.CCMP);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.NONE);
config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
break;
}
default: {
break;
}
}
return config;
}
十、ScrollView嵌套listView的问题
会使listView的高度显示不全 我以我们应该过去每个item视图 然后调用measure()测量下高度 累加 然后设置到listView上
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
滑动问题 要通过继承视图 在拦截事件
十一、圆角
editText的圆角组件
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" android:padding="10dp">
<solid android:color="#FFFFFF" />
<corners android:bottomRightRadius="15dp"
android:bottomLeftRadius="15dp" android:topLeftRadius="15dp"
android:topRightRadius="15dp" />
<stroke
android:width="1dip"
android:color="#728ea3" />
</shape>
重要的
将组件的background=".xml"
圆角图片:
思路: 先获取到一个Bitmap 在new Canvas 这是覆盖原理 把canvas画与bitmap的交集取出来 显示 重点是paint.setXfermode(new
PorterDuffXfermode(Mode.SRC_IN));
代码:
private Bitmap getBitmap(int size) {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.t);
Bitmap scalebm = Bitmap.createScaledBitmap(bitmap, size, size, true);
Bitmap output = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_4444);
Paint paint = new Paint();
paint.setAntiAlias(true);
Canvas canvas = new Canvas(output);
canvas.drawCircle(size / 2, size / 2, size / 2, paint);
// 设置取两层图形的交集,并且只显示上层的图片
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(scalebm, 0, 0, paint);
return output;
}
十二、启动另一个App
在一个app中启动另一个app
先获取要启动的app包名,然后在package管理器中根据intent查找 返回一个集合 迭代 如果有就获取包名和类名 在启动这个app
// 通过包名获取此APP详细信息,包括Activities、services、versioncode、name等等
PackageInfo packageinfo = null;
try {
packageinfo = c.getPackageManager().getPackageInfo(packagename, 0);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
if (packageinfo == null) {
return;
}
// 创建一个类别为CATEGORY_LAUNCHER的该包名的Intent
Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
resolveIntent.setPackage(packageinfo.packageName);
// 通过getPackageManager()的queryIntentActivities方法遍历
List<ResolveInfo> resolveinfoList = c.getPackageManager()
.queryIntentActivities(resolveIntent, 0);
ResolveInfo resolveinfo = resolveinfoList.iterator().next();
if (resolveinfo != null) {
// packagename = 参数packname
String packageName = resolveinfo.activityInfo.packageName;
// 这个就是我们要找的该APP的LAUNCHER的Activity[组织形式:packagename.mainActivityname]
String className = resolveinfo.activityInfo.name;
// LAUNCHER Intent
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
// 设置ComponentName参数1:packagename参数2:MainActivity路径
ComponentName cn = new ComponentName(packageName, className);
intent.setComponent(cn);
c.startActivity(intent);
}
十三、调节屏幕亮度
这个单词 SCREEN_BRIGHTNESS 是屏幕亮度
获取屏幕亮度 normal = Settings.System.getInt(getContentResolver(),Settings.System.SCREEN_BRIGHTNESS, tempInt);
设置屏幕亮度 Settings.System.putInt(getContentResolver(),Settings.System.SCREEN_BRIGHTNESS, progress);
LayoutParams wl = getWindow().getAttributes();
wl.screenBrightness = normal;
getWindow().setAttributes(wl);
权限: <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
就OK了
十四、GPS定位
权限: <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
先通过 (LocationManager)getSystemServer(LOCATION_SERVER); //获取locationManager对象
在通过 requestLocationUpdates()绑定一个Listener
如: //这是通过网络获取位置
manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 2000,
0, mLocation);
绑定的是LocationListener 其中有四个重写的方法
onStatusChanged onProviderEnabled onProviderDisabled onLocationChanged
我们在onLocationChanged(Location location) 中获取经纬度 因为这个参数中包含Location对象
十五、 图片上加文字
先获取到一张图片 通过canvas 的drawText方法画
Bitmap bit = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher).copy(Config.ARGB_8888, true); // 这个必须是Config.ARGB_8888 4444的
不行
Canvas canvas = new Canvas(bit);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
canvas.drawText("我叫***", 20, 26, paint);
img.setImageBitmap(bit);
十六、 更新app
权限 : <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
首先先将工程中放个文件 如:version.xml 里面有有三个标签 一个是新版本的版本号 名称 url
注意:xml里的一个标签及标签内的数据都要在一行 否则判断的时候一直是不相等
通过xmlPullFactory解析出来 在获取当前的版本号getPackageManager
用着俩个版本号对比 如何不相等则去更新 相等就提示用户已经是最新版本
通过handler不断的使progressDialog的title不断的变化 正在更新. 正在更新.. 正在更新...
更新:通过httpURLConnection 连接url地址 下载 并保存到文件 在通过intent 安装apk
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://文件.toString", "application/vnd.android.package-archive" ));
startActivity(intent);
加载工程中的文件 并返回流:MyParser.class.getClassLoader().getResourceAsStream("version.xml")
十七、 浮动窗口
手机中在设置得启动浮动窗口权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
通过启动一个服务 基本都是getAppincation.什么 是他不是与Activity的生命周期绑定
getApplication.getSystemServer(getApplication.WINDOW_SERVSER);//获取到window管理器
LayoutParams params = new WindowManager.LayoutParams();//获取个layoutParams();
重点是设置params的type LayoutParams.TYPE_PHONE
在设置一些属性 params.x 或params.y 什么的...
通过windowManager.addView(view,parmas);添加及显示出来
通过windowMnaager.updateViewLayout(view,params);方法更新
通过windowManager.removeView(view); 移除视图
十八、 调节音量
获取音量管理器
AudioManager manager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
//设置音量 还可以设置其他音量 第一个参数
manager.setStreamVolume(AudioManager.STREAM_MUSIC, progress,
AudioManager.FLAG_PLAY_SOUND);
十九、 DownLoadManager
概述
在android的开发中,经会使用到文件下载的功能 不如:app版本的更新,在api leve9后,android系统提供了
DownLoadManager类,把下载的整个过程都交给他,不同我们过多的处理
DownLoadManager包含俩个类
DownLoadManager.Query 主要用于查询下载信息。
DownLoadManager.Request 主要用于发起一个下载请求。
首先我们获取到
DownLoadManager download=(DownLoadManager)Context.getSystemServer(Context.DOWNLOAD_SERVER);
Request request = new Request(Uri.parse("http://dingphone.ufile.ucloud.com.cn/apk/guanwang/time2plato.apk"));
通过download.enqueue(request); 方法执行下载 并会返回当前下载的id
Request 中的方法
addRequestHeader(String header,String value):添加网络下载请求的http头信息
allowScanningByMediaScanner():用于设置是否允许本MediaScanner扫描。
setAllowedNetworkTypes(int flags):设置用于下载时的网络类型,默认任何网络都可以下载,提供的网络常量有:NETWORK_BLUETOOTH、
NETWORK_MOBILE、NETWORK_WIFI。
setAllowedOverRoaming(Boolean allowed):用于设置漫游状态下是否可以下载
setNotificationVisibility(int visibility):用于设置下载时时候在状态栏显示通知信息
setTitle(CharSequence):设置Notification的title信息
setDescription(CharSequence):设置Notification的message信息
setDestinationInExternalFilesDir、setDestinationInExternalPublicDir、 setDestinationUri等方法用于设置下载文件的存放路径,注意
如果将下载文件存放在默认路径,那么在空间不足的情况下系统会将文件删除,所 以使用上述方法设置文件存放目录是十分必要的。
request.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOWNLOADS,"bolin.apk");
下载完我们需要让他通知我们 我们在创建个广播 在注册的时候我们要过滤完成的动作 <action
android:name="android.intent.action.DOWNLOAD_COMPLETE" />
我们在通过 long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); 获取到下载完的id
在通过downLoad的 uid=getUriForDownloadedFile(id) //获取到uri
在调用intent安装app
Intent ten = new Intent(Intent.ACTION_VIEW);
ten.setDataAndType(uid, "application/vnd.android.package-archive");
ten.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(ten)
权限 联网 文件写
完成!
二十、 安装app与卸载app
权限
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/>
安装app
File file = new File(apkPath);
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
String type = "application/vnd.android.package-archive";
intent.setDataAndType(Uri.fromFile(file), type);
c.startActivity(intent);
卸载app
Intent intent = new Intent(Intent.ACTION_DELETE, Uri.parse("package:"
+ packName));
c.startActivity(intent);
通过包管理器 能够获取所有app的信息
PackageManager packageManager = getPackageManager();
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> activitys = packageManager.queryIntentActivities(
intent, PackageManager.MATCH_DEFAULT_ONLY);
修改桌面壁纸
WallpaperManager wallpaper = WallpaperManager.getInstance(this);
wallpaper.setResource(arr[i]);
进入应用商城给应用评分
Uri uri = Uri.parse("market://details?id=" +"com.estrongs.android.pop.view.FileExplorerActivity" );
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
二十一、Studio报重复图片异常
packagingOptions {
exclude 'assets/Icon_start.png'
}
二十二、 JNI
什么是JNI
JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为java平
台的一部分,它允许Java代码和其他 语言写的代码进行交互。
NDK和JNI的关系
JNI是接口规范,NDK是工具集合,使用NDK就可以按JNI接口规范在Android平台使用c/c++编程并被Java代码调用。
首先下载个NDK并配置到stuio上 sdk版本24
通过native关键字调用c/c++代码
我们需要与java文件同级下建立个cpp文件夹
在此文件夹下创建个c++文件 如: native-lib.cpp
native-lib文件中定义的方法要与native关键字所在的方法名相同
native-lib文件中方法格式 Java_包名_类名_方法名
通过include 导包
如:
#include <jni.h>
#include <string>
extern "C"
jstring //返回值
Java_com_example_dsy_myndk_MyJNI_getData(JNIEnv* env,jobject obj,jstring str){
return str;
}
二十三、 编写c++代码
#include <stdio.h> // 是头引用
#include <string> //引用string库
#include <iostream> //可以调用 std::cout <<"我叫戴舒予" <<变量值 <<std::endl
extern 方法返回值 方法(参数); //引用别的.cpp文件的方法
#define Height 10;//这是定义常量
using namespace //使用std这个名字空间。标准库里面的东西都是处于std名字空间的。
如果不写这句,你写cin和cout时候就必须这样写,否则找不到cin或者cout
cout <<" " <<变量 <<还可以加 <<endl; //打印信息
cin >> 类型变量 >>还可以填; //用户可以输入
clog <<"Error" <<str<<endl; //这是log
rand() //生成随机数
//定义方法模块语法
方法一 这种方式得自己定义引用
struct Books{
数据类型 名;
};
//引用方法
Books book1;
book1.名;
方法二
struct Books{
数据类型 名;
}book1;
//引用方法
book1.名;
//将对象作为参数放在方法里
string getBook(struct Books book){
return book.book_name;
}
二十四、listView浮动效果
实现原理:外层是scrollView中嵌套FramLayout 将要浮动的布局设置到浮动的位置 并隐藏
监听scrollView滚动监听
int mBuyLayout2ParentTop = Math.max(t, mBuyLayout.getTop()); //获取到布局中悬浮部分的高和滚动的Y坐标
layout.layout(0, mBuyLayout2ParentTop, layout.getWidth(),mBuyLayout2ParentTop + layout.getHeight());
//该方法是前俩个参数是x,y位置 后俩个参数是宽高 设置隐藏布局的位置
layout.setVisibility(View.VISIBLE);
二十五、自定义HorizontalScrollView实现侧滑
实现原理:自定义一个HorizontalScrollView 重写构造方法、onMeasure()、onLayout、onScrollChanged、onTouchEvent()
1. 构造方法中获取屏幕的宽度
WindowManager manager=(WindowManager)context.getSystemService(context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
screenWidth = outMetrics.widthPixels;
// 将dp转换px
myMenuPaddingRight = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 70, context.getResources()
.getDisplayMetrics());
2.onMeasure() 获取子布局并设置宽度
LinearLayout linear = (LinearLayout) getChildAt(0);
// 获取子组件中的子组件
item_1 = linear.getChildAt(0);
item_2 = linear.getChildAt(1);
// 给Menu页面设置宽度
myMenuWidth = item_1.getLayoutParams().width = screenWidth
- myMenuPaddingRight;
// 给第二个页面设置宽度
item_2.getLayoutParams().width = screenWidth;
3.onLayout() 默认移动到第二屏
this.smoothScrollTo(myMenuWidth, 0);
4.onTouchEvent() 获取当前用户是向哪滑
switch (ev.getAction()) {
case MotionEvent.ACTION_UP:
int scrollX = this.getScrollX();
Log.e("main", "这是ScrollX" + scrollX);
if (scrollX >= myMenuWidth / 2) {
this.smoothScrollTo(myMenuWidth, 0);
} else {
this.smoothScrollTo(0, 0);
}
return true; //这里必须return true 否则smoothScrollTo();方法没有滚动过程的效果
}
5.onScrollChanged()滚动改变的时候调用 在这里面设置动画效果 这里导入了第三方的jar包nineoldandroids-2.4.0.jar
float scale = l * 1.0f / myMenuWidth; // 1 ~ 0
/**
* 区别1:内容区域1.0~0.7 缩放的效果 scale : 1.0~0.0 0.7 + 0.3 * scale
*
* 区别2:菜单的偏移量需要修改
*
* 区别3:菜单的显示时有缩放以及透明度变化 缩放:0.7 ~1.0 1.0 - scale * 0.3 透明度 0.6 ~ 1.0 0.6+
* 0.4 * (1- scale) ;
*
*/
float rightScale = 0.7f + 0.3f * scale;
float leftScale = 1.0f - scale * 0.3f;
float leftAlpha = 0.6f + 0.4f * (1 - scale);
// 调用属性动画,设置TranslationX
ViewHelper.setTranslationX(item_1, myMenuWidth * scale * 0.8f);
ViewHelper.setScaleX(item_1, leftScale);
ViewHelper.setScaleY(item_1, leftScale);
ViewHelper.setAlpha(item_1, leftAlpha);
// 设置content的缩放的中心点
ViewHelper.setPivotX(item_2, 0);
ViewHelper.setPivotY(item_2, item_2.getHeight() / 2);
ViewHelper.setScaleX(item_2, rightScale);
ViewHelper.setScaleY(item_2, rightScale);
二十六、将android工程打成jar并在别的工程中引用
不要选择androidmanifest.xml和res文件夹,就可以了。否则在调用jar包的时候会出现“Error generating final archive: Found duplicate
file for APK: AndroidManifes”这个错误。
对于使用jar方式进行组件开发,有以下需要注意:
1. jar包中一般只包含代码不包含资源。
2. 如果要在jar中包含资源,则资源文件不应该放在默认的res目录下(因为导入其他项目后可能出现重名冲突),应该在package目录下创建专用的资源
目录,如此通过pakcage的不重名来确保导入后资源不冲突。同时,jar中代码不能直接使用R类中资源id进行访问,应该通过getClass
().getClassLoader().getResourceAsStream()进行加载。
3. 字付串资源可以定义成常量的方式来使用。
二十七、电话与信息
//加权限
直接发信息
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, "信息内容");
SmsManager smsManager = SmsManager.getDefault();
PendingIntent req = PendingIntent.getActivity(this, 100, new Intent(
MainActivity.this, MainActivity.class), 0);
smsManager.sendTextMessage("***********", null, "我是***", req, null);
间接发送信息:
Intent intent = new Intent(Intent.ACTION_SENDTO,
Uri.parse("sms:18210124754"));
intent.putExtra(Intent.EXTRA_TEXT, "SENDTo");
startActivity(intent);
直接打电话:
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:1008611"));
startActivity(intent);
间接打电话:
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:1008611"));
startActivity(intent);
还可以通过电话管理 TelephonyManager telManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
telManager.listener(对象,PhoneStateListener.什么);
对象里重写需要的方法
可以知道电话的状态 位置信息 网络信息 .....
二十八、androidStudio单元测试
在test文件下是单元测试的类 在该类里创建个方法并加上@Test 就像是main方法中使用别的类方法一样调用 并将运行按钮边上的改成
ExampleUnitText 如何你要运行项目的话还会app
二十九、从网络获取视频图片缩略图
同过 MediaMetadataRetriever.setDataSource()给定一个URI 在getFrameAtTime()获取一个bitmap 在通过
ThumbnailUtils.extractThumbnail() 进行压缩
corners属性是设置角度的 solid是设置颜色的 gradient用于渐变色的 stroke这是描边的 (这个必须要设置宽度 然后设置颜色 要不就没效果)
shape设置形状 (默认为矩形,可以设置为矩形(rectangle)、椭圆形(oval)、线性形状(line)、环形(ring))
DataPickDialog timepickDialog 这是一个时间和日期的dialog空间
三十、注意
5.0以后不能隐士启动服务
setTag 将图片的url设置上
在放图片的时候先取Tag 判断俩个是否相等 相等再去设置
二、edtiText加载图片
SpannableString 与String的区别是可以设置样式如果组件不支持就成为String了,
span()是设置样式的
源码
SpannableString builder = new SpannableString(et.getText()
.toString()+"");
ImageSpan img = new ImageSpan(MainActivity.this,
R.drawable.ic_launcher);
builder.setSpan(img, et.getText().toString().length(), et
.getText().toString().length() + 1,
Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
et.setText(builder);
三、Gson解析
也是像json一层一层来解析,与json不同的是gson封装的是对象
四、缓存技术
softReference weakReference lruCache
第一次是从网络下载的根据uri保存到缓存并保存到sd卡(这里需要获取看有没有) 显示的时候 先从缓存(lruCache)中获取如果有就显示 没有就
从sd卡获取
如何有就显示并添加到缓存里(lruCache) 没有在从网络获取在添加到缓存和集合中
五、断点续传
RandomAccessFile 有指针 通过指针获取位置
FileOutputStream 构造方法两个参数的 true代表将数据追加到文件末尾
过程 从网络上获取用RandomAccessFile 并用FileOutputStream 写入文件 写入过程并将RandomAccessFile.getFilePointer()和文件名 写入数据
库 如何网络断了 就根据
文件名取文件的pointer值 通过RandomAccessFile.seek();设置从哪开始
异常: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
android 中数据库处理,特别是使用cursor时,注意初始位置,好像是从下标为-1的地方开始的,也就是说一次查询中,返回给cursor查询结
果时,不能够马上从cursor中提取值。
cursor.moveToFirst()
六、Parcelable
写一个类 实现 parcelable接口 写要保存数据的字段 setget方法 在
protected MyParcelable(Parcel in) {
mData = in.readInt();
time=in.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mData);
dest.writeString(time);
}
就OK了
七、 faceDetor 人脸识别技术
注意的有图片
八、蓝牙
蓝牙是API level 5 就有的一个技术 虽然现在这个技术很少使用 但是我们还是要学一学的
wifi 技术是一个崭新的时代 他替代了蓝牙 (这是我个人认为) 我们要向新时代去努力!!!
客户端
private static final UUID MY_UUID_SECURE = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66"); //安全的
private static final UUID MY_UUID_INSECURE = UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66"); //不安全的
首先我们先将蓝牙的权限加上
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
要想扫描到蓝牙 蓝牙必须是可见的
通过intent 启动 BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE 就可以将蓝牙可见
蓝牙可见了我们就获取获取蓝牙的适配器
BluetoothAdapter.getDefaultAdapter();
在通过蓝牙适配器的startDiscovery() 方法开始扫描周边可见的蓝牙 通过绑定广播过滤 new IntentFilter(BluetoothDevice.ACTION_FOUND)
//代表找到了蓝牙
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); //获取到蓝牙的驱动 根据驱动来获取 地址及其相
关信息
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
}
也可以通过getBondedDevices() 获取驱动 这个方法返回的是一个集合
要想连接服务器 我们通过驱动获取地址 通过getRemoteDevice(address); 获取到指定蓝牙的驱动
在通过这个驱动的 createInsecureRfcommSocketToServiceRecord(MY_UUID_INSECURE); //这个是不安全的是不需要验证的
createRfcommSocketToServiceRecord(MY_UUID_SECURE); //这个是安全的需要验证的
他俩都会返回一个BluetoothSocket 对象 我们通过他调用 connect() 和服务器端连接
如果连接成功 就可以通过他获取input 或 output 流 来写去和读取
服务器端
我们通过 BlueAdapter的 listenUsingInsecureRfcommWithServiceRecord(NAME_INSECURE,MY_UUID_INSECURE);//不安全的 这俩个方法 是与客
户端的俩个方法对应的
listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE); //安全的
他们会返回一个BluetoothServerSocket 对象 在通过这个对象的 accpet()方法(注意这个方法是会阻塞主线程的 我们要将他放到子线程 )
返回一个BluetoothSocket 对象
在通过socket对象 获取input或output流来传输数据
蓝牙讲解完毕,有什么不对还请您指点!!!
九、Wifi
权限:
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <!-- 允许程序改变网络链接状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><!-- 允许程序访问访问WIFI网络状态信息 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /><!-- 允许程序改变WIFI链接状态 -->
<uses-permission android:name="android.permission.INTERNET" />
先获取WifiManager对象
WifiManager manager=getSystemService(WifiManager.WIFI_SERVICE);
通过setWifiEnabled()方法设置wifi打开与关闭
通过调用 startScan()扫描周围的热点
通过绑定广播 过滤WifiManager.SCAN_RESULTS_AVAILABLE_ACTION
通过manager.getScanResults();获取扫描的热点
获取要连接的热点的capabilities和SSID
capabilities是一种加密模式 如WPA2 WPA WEP
首先调用addNetwork(); 会有个返回值 根据返回值判断 -1代表失败 这里需要一个WifiConfiguration对象
调用 manager.enableNetwork(netId, true); 连接wifi
public WifiConfiguration generateWifiConfiguration(AuthenticationType type,
String ssid, String password) {
WifiConfiguration config = new WifiConfiguration();
config.SSID = String.format("\"%s\"", ssid);
switch (type) {
case TYPE_NONE: {
config.wepKeys[0] = "\"\"";
config.wepTxKeyIndex = 0;
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
break;
}
case TYPE_WEP: {
config.wepKeys[0] = String.format("\"%s\"", password);
config.wepTxKeyIndex = 0;
config.allowedAuthAlgorithms
.set(WifiConfiguration.AuthAlgorithm.SHARED);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
config.allowedGroupCiphers
.set(WifiConfiguration.GroupCipher.WEP104);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
break;
}
case TYPE_WPA: {
config.preSharedKey = String.format("\"%s\"", password);
config.allowedAuthAlgorithms
.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.CCMP);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.NONE);
config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
break;
}
case TYPE_WPA2: {
config.preSharedKey = String.format("\"%s\"", password);
config.allowedAuthAlgorithms
.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.CCMP);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.NONE);
config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
break;
}
default: {
break;
}
}
return config;
}
十、ScrollView嵌套listView的问题
会使listView的高度显示不全 我以我们应该过去每个item视图 然后调用measure()测量下高度 累加 然后设置到listView上
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
滑动问题 要通过继承视图 在拦截事件
或继承listView
添加
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
十一、圆角
editText的圆角组件
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" android:padding="10dp">
<solid android:color="#FFFFFF" />
<corners android:bottomRightRadius="15dp"
android:bottomLeftRadius="15dp" android:topLeftRadius="15dp"
android:topRightRadius="15dp" />
<stroke
android:width="1dip"
android:color="#728ea3" />
</shape>
重要的
将组件的background=".xml"
圆角图片:
思路: 先获取到一个Bitmap 在new Canvas 这是覆盖原理 把canvas画与bitmap的交集取出来 显示 重点是paint.setXfermode(new
PorterDuffXfermode(Mode.SRC_IN));
代码:
private Bitmap getBitmap(int size) {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.t);
Bitmap scalebm = Bitmap.createScaledBitmap(bitmap, size, size, true);
Bitmap output = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_4444);
Paint paint = new Paint();
paint.setAntiAlias(true);
Canvas canvas = new Canvas(output);
canvas.drawCircle(size / 2, size / 2, size / 2, paint);
// 设置取两层图形的交集,并且只显示上层的图片
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(scalebm, 0, 0, paint);
return output;
}
十二、启动另一个App
在一个app中启动另一个app
先获取要启动的app包名,然后在package管理器中根据intent查找 返回一个集合 迭代 如果有就获取包名和类名 在启动这个app
// 通过包名获取此APP详细信息,包括Activities、services、versioncode、name等等
PackageInfo packageinfo = null;
try {
packageinfo = c.getPackageManager().getPackageInfo(packagename, 0);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
if (packageinfo == null) {
return;
}
// 创建一个类别为CATEGORY_LAUNCHER的该包名的Intent
Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
resolveIntent.setPackage(packageinfo.packageName);
// 通过getPackageManager()的queryIntentActivities方法遍历
List<ResolveInfo> resolveinfoList = c.getPackageManager()
.queryIntentActivities(resolveIntent, 0);
ResolveInfo resolveinfo = resolveinfoList.iterator().next();
if (resolveinfo != null) {
// packagename = 参数packname
String packageName = resolveinfo.activityInfo.packageName;
// 这个就是我们要找的该APP的LAUNCHER的Activity[组织形式:packagename.mainActivityname]
String className = resolveinfo.activityInfo.name;
// LAUNCHER Intent
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
// 设置ComponentName参数1:packagename参数2:MainActivity路径
ComponentName cn = new ComponentName(packageName, className);
intent.setComponent(cn);
c.startActivity(intent);
}
十三、调节屏幕亮度
这个单词 SCREEN_BRIGHTNESS 是屏幕亮度
获取屏幕亮度 normal = Settings.System.getInt(getContentResolver(),Settings.System.SCREEN_BRIGHTNESS, tempInt);
设置屏幕亮度 Settings.System.putInt(getContentResolver(),Settings.System.SCREEN_BRIGHTNESS, progress);
LayoutParams wl = getWindow().getAttributes();
wl.screenBrightness = normal;
getWindow().setAttributes(wl);
权限: <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
就OK了
十四、GPS定位
权限: <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
先通过 (LocationManager)getSystemServer(LOCATION_SERVER); //获取locationManager对象
在通过 requestLocationUpdates()绑定一个Listener
如: //这是通过网络获取位置
manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 2000,
0, mLocation);
绑定的是LocationListener 其中有四个重写的方法
onStatusChanged onProviderEnabled onProviderDisabled onLocationChanged
我们在onLocationChanged(Location location) 中获取经纬度 因为这个参数中包含Location对象
十五、 图片上加文字
先获取到一张图片 通过canvas 的drawText方法画
Bitmap bit = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher).copy(Config.ARGB_8888, true); // 这个必须是Config.ARGB_8888 4444的
不行
Canvas canvas = new Canvas(bit);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
canvas.drawText("我叫***", 20, 26, paint);
img.setImageBitmap(bit);
十六、 更新app
权限 : <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
首先先将工程中放个文件 如:version.xml 里面有有三个标签 一个是新版本的版本号 名称 url
注意:xml里的一个标签及标签内的数据都要在一行 否则判断的时候一直是不相等
通过xmlPullFactory解析出来 在获取当前的版本号getPackageManager
用着俩个版本号对比 如何不相等则去更新 相等就提示用户已经是最新版本
通过handler不断的使progressDialog的title不断的变化 正在更新. 正在更新.. 正在更新...
更新:通过httpURLConnection 连接url地址 下载 并保存到文件 在通过intent 安装apk
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://文件.toString", "application/vnd.android.package-archive" ));
startActivity(intent);
加载工程中的文件 并返回流:MyParser.class.getClassLoader().getResourceAsStream("version.xml")
十七、 浮动窗口
手机中在设置得启动浮动窗口权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
通过启动一个服务 基本都是getAppincation.什么 是他不是与Activity的生命周期绑定
getApplication.getSystemServer(getApplication.WINDOW_SERVSER);//获取到window管理器
LayoutParams params = new WindowManager.LayoutParams();//获取个layoutParams();
重点是设置params的type LayoutParams.TYPE_PHONE
在设置一些属性 params.x 或params.y 什么的...
通过windowManager.addView(view,parmas);添加及显示出来
通过windowMnaager.updateViewLayout(view,params);方法更新
通过windowManager.removeView(view); 移除视图
十八、 调节音量
获取音量管理器
AudioManager manager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
//设置音量 还可以设置其他音量 第一个参数
manager.setStreamVolume(AudioManager.STREAM_MUSIC, progress,
AudioManager.FLAG_PLAY_SOUND);
十九、 DownLoadManager
概述
在android的开发中,经会使用到文件下载的功能 不如:app版本的更新,在api leve9后,android系统提供了
DownLoadManager类,把下载的整个过程都交给他,不同我们过多的处理
DownLoadManager包含俩个类
DownLoadManager.Query 主要用于查询下载信息。
DownLoadManager.Request 主要用于发起一个下载请求。
首先我们获取到
DownLoadManager download=(DownLoadManager)Context.getSystemServer(Context.DOWNLOAD_SERVER);
Request request = new Request(Uri.parse("http://dingphone.ufile.ucloud.com.cn/apk/guanwang/time2plato.apk"));
通过download.enqueue(request); 方法执行下载 并会返回当前下载的id
Request 中的方法
addRequestHeader(String header,String value):添加网络下载请求的http头信息
allowScanningByMediaScanner():用于设置是否允许本MediaScanner扫描。
setAllowedNetworkTypes(int flags):设置用于下载时的网络类型,默认任何网络都可以下载,提供的网络常量有:NETWORK_BLUETOOTH、
NETWORK_MOBILE、NETWORK_WIFI。
setAllowedOverRoaming(Boolean allowed):用于设置漫游状态下是否可以下载
setNotificationVisibility(int visibility):用于设置下载时时候在状态栏显示通知信息
setTitle(CharSequence):设置Notification的title信息
setDescription(CharSequence):设置Notification的message信息
setDestinationInExternalFilesDir、setDestinationInExternalPublicDir、 setDestinationUri等方法用于设置下载文件的存放路径,注意
如果将下载文件存放在默认路径,那么在空间不足的情况下系统会将文件删除,所 以使用上述方法设置文件存放目录是十分必要的。
request.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOWNLOADS,"bolin.apk");
下载完我们需要让他通知我们 我们在创建个广播 在注册的时候我们要过滤完成的动作 <action
android:name="android.intent.action.DOWNLOAD_COMPLETE" />
我们在通过 long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); 获取到下载完的id
在通过downLoad的 uid=getUriForDownloadedFile(id) //获取到uri
在调用intent安装app
Intent ten = new Intent(Intent.ACTION_VIEW);
ten.setDataAndType(uid, "application/vnd.android.package-archive");
ten.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(ten)
权限 联网 文件写
完成!
二十、 安装app与卸载app
权限
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/>
安装app
File file = new File(apkPath);
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
String type = "application/vnd.android.package-archive";
intent.setDataAndType(Uri.fromFile(file), type);
c.startActivity(intent);
卸载app
Intent intent = new Intent(Intent.ACTION_DELETE, Uri.parse("package:"
+ packName));
c.startActivity(intent);
通过包管理器 能够获取所有app的信息
PackageManager packageManager = getPackageManager();
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> activitys = packageManager.queryIntentActivities(
intent, PackageManager.MATCH_DEFAULT_ONLY);
修改桌面壁纸
WallpaperManager wallpaper = WallpaperManager.getInstance(this);
wallpaper.setResource(arr[i]);
进入应用商城给应用评分
Uri uri = Uri.parse("market://details?id=" +"com.estrongs.android.pop.view.FileExplorerActivity" );
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
二十一、Studio报重复图片异常
packagingOptions {
exclude 'assets/Icon_start.png'
}
二十二、 JNI
什么是JNI
JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为java平
台的一部分,它允许Java代码和其他 语言写的代码进行交互。
NDK和JNI的关系
JNI是接口规范,NDK是工具集合,使用NDK就可以按JNI接口规范在Android平台使用c/c++编程并被Java代码调用。
首先下载个NDK并配置到stuio上 sdk版本24
通过native关键字调用c/c++代码
我们需要与java文件同级下建立个cpp文件夹
在此文件夹下创建个c++文件 如: native-lib.cpp
native-lib文件中定义的方法要与native关键字所在的方法名相同
native-lib文件中方法格式 Java_包名_类名_方法名
通过include 导包
如:
#include <jni.h>
#include <string>
extern "C"
jstring //返回值
Java_com_example_dsy_myndk_MyJNI_getData(JNIEnv* env,jobject obj,jstring str){
return str;
}
二十三、 编写c++代码
#include <stdio.h> // 是头引用
#include <string> //引用string库
#include <iostream> //可以调用 std::cout <<"我叫戴舒予" <<变量值 <<std::endl
extern 方法返回值 方法(参数); //引用别的.cpp文件的方法
#define Height 10;//这是定义常量
using namespace //使用std这个名字空间。标准库里面的东西都是处于std名字空间的。
如果不写这句,你写cin和cout时候就必须这样写,否则找不到cin或者cout
cout <<" " <<变量 <<还可以加 <<endl; //打印信息
cin >> 类型变量 >>还可以填; //用户可以输入
clog <<"Error" <<str<<endl; //这是log
rand() //生成随机数
//定义方法模块语法
方法一 这种方式得自己定义引用
struct Books{
数据类型 名;
};
//引用方法
Books book1;
book1.名;
方法二
struct Books{
数据类型 名;
}book1;
//引用方法
book1.名;
//将对象作为参数放在方法里
string getBook(struct Books book){
return book.book_name;
}
二十四、listView浮动效果
实现原理:外层是scrollView中嵌套FramLayout 将要浮动的布局设置到浮动的位置 并隐藏
监听scrollView滚动监听
int mBuyLayout2ParentTop = Math.max(t, mBuyLayout.getTop()); //获取到布局中悬浮部分的高和滚动的Y坐标
layout.layout(0, mBuyLayout2ParentTop, layout.getWidth(),mBuyLayout2ParentTop + layout.getHeight());
//该方法是前俩个参数是x,y位置 后俩个参数是宽高 设置隐藏布局的位置
layout.setVisibility(View.VISIBLE);
二十五、自定义HorizontalScrollView实现侧滑
实现原理:自定义一个HorizontalScrollView 重写构造方法、onMeasure()、onLayout、onScrollChanged、onTouchEvent()
1. 构造方法中获取屏幕的宽度
WindowManager manager=(WindowManager)context.getSystemService(context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
screenWidth = outMetrics.widthPixels;
// 将dp转换px
myMenuPaddingRight = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 70, context.getResources()
.getDisplayMetrics());
2.onMeasure() 获取子布局并设置宽度
LinearLayout linear = (LinearLayout) getChildAt(0);
// 获取子组件中的子组件
item_1 = linear.getChildAt(0);
item_2 = linear.getChildAt(1);
// 给Menu页面设置宽度
myMenuWidth = item_1.getLayoutParams().width = screenWidth
- myMenuPaddingRight;
// 给第二个页面设置宽度
item_2.getLayoutParams().width = screenWidth;
3.onLayout() 默认移动到第二屏
this.smoothScrollTo(myMenuWidth, 0);
4.onTouchEvent() 获取当前用户是向哪滑
switch (ev.getAction()) {
case MotionEvent.ACTION_UP:
int scrollX = this.getScrollX();
Log.e("main", "这是ScrollX" + scrollX);
if (scrollX >= myMenuWidth / 2) {
this.smoothScrollTo(myMenuWidth, 0);
} else {
this.smoothScrollTo(0, 0);
}
return true; //这里必须return true 否则smoothScrollTo();方法没有滚动过程的效果
}
5.onScrollChanged()滚动改变的时候调用 在这里面设置动画效果 这里导入了第三方的jar包nineoldandroids-2.4.0.jar
float scale = l * 1.0f / myMenuWidth; // 1 ~ 0
/**
* 区别1:内容区域1.0~0.7 缩放的效果 scale : 1.0~0.0 0.7 + 0.3 * scale
*
* 区别2:菜单的偏移量需要修改
*
* 区别3:菜单的显示时有缩放以及透明度变化 缩放:0.7 ~1.0 1.0 - scale * 0.3 透明度 0.6 ~ 1.0 0.6+
* 0.4 * (1- scale) ;
*
*/
float rightScale = 0.7f + 0.3f * scale;
float leftScale = 1.0f - scale * 0.3f;
float leftAlpha = 0.6f + 0.4f * (1 - scale);
// 调用属性动画,设置TranslationX
ViewHelper.setTranslationX(item_1, myMenuWidth * scale * 0.8f);
ViewHelper.setScaleX(item_1, leftScale);
ViewHelper.setScaleY(item_1, leftScale);
ViewHelper.setAlpha(item_1, leftAlpha);
// 设置content的缩放的中心点
ViewHelper.setPivotX(item_2, 0);
ViewHelper.setPivotY(item_2, item_2.getHeight() / 2);
ViewHelper.setScaleX(item_2, rightScale);
ViewHelper.setScaleY(item_2, rightScale);
二十六、将android工程打成jar并在别的工程中引用
不要选择androidmanifest.xml和res文件夹,就可以了。否则在调用jar包的时候会出现“Error generating final archive: Found duplicate
file for APK: AndroidManifes”这个错误。
对于使用jar方式进行组件开发,有以下需要注意:
1. jar包中一般只包含代码不包含资源。
2. 如果要在jar中包含资源,则资源文件不应该放在默认的res目录下(因为导入其他项目后可能出现重名冲突),应该在package目录下创建专用的资源
目录,如此通过pakcage的不重名来确保导入后资源不冲突。同时,jar中代码不能直接使用R类中资源id进行访问,应该通过getClass
().getClassLoader().getResourceAsStream()进行加载。
3. 字付串资源可以定义成常量的方式来使用。
二十七、电话与信息
//加权限
直接发信息
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, "信息内容");
SmsManager smsManager = SmsManager.getDefault();
PendingIntent req = PendingIntent.getActivity(this, 100, new Intent(
MainActivity.this, MainActivity.class), 0);
smsManager.sendTextMessage("***********", null, "我是***", req, null);
间接发送信息:
Intent intent = new Intent(Intent.ACTION_SENDTO,
Uri.parse("sms:18210124754"));
intent.putExtra(Intent.EXTRA_TEXT, "SENDTo");
startActivity(intent);
直接打电话:
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:1008611"));
startActivity(intent);
间接打电话:
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:1008611"));
startActivity(intent);
还可以通过电话管理 TelephonyManager telManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
telManager.listener(对象,PhoneStateListener.什么);
对象里重写需要的方法
可以知道电话的状态 位置信息 网络信息 .....
二十八、androidStudio单元测试
在test文件下是单元测试的类 在该类里创建个方法并加上@Test 就像是main方法中使用别的类方法一样调用 并将运行按钮边上的改成
ExampleUnitText 如何你要运行项目的话还会app
二十九、从网络获取视频图片缩略图
同过 MediaMetadataRetriever.setDataSource()给定一个URI 在getFrameAtTime()获取一个bitmap 在通过
ThumbnailUtils.extractThumbnail() 进行压缩
corners属性是设置角度的 solid是设置颜色的 gradient用于渐变色的 stroke这是描边的 (这个必须要设置宽度 然后设置颜色 要不就没效果)
shape设置形状 (默认为矩形,可以设置为矩形(rectangle)、椭圆形(oval)、线性形状(line)、环形(ring))
DataPickDialog timepickDialog 这是一个时间和日期的dialog空间
三十、注意
5.0以后不能隐士启动服务