都可以实现锁屏界面的旋转
java.text.DateFormat.LONG, locale); ->java.text.DateFormat.LONG, Locale.UK); //24小时格式
java.text.DateFormat.LONG, locale); ->java.text.DateFormat.LONG, Locale.US.); //12小时格式
修改默认时间
mtk中默认时间设置:
alpsmediatekcustom[project]preloader inccust_rtc.h
alpsmediatekcustom[project]kernel tc tc tc-mt65XX.h
#define RTC_DEFAULT_YEA 2010
#define RTC_DEFAULT_MTH 1
#define RTC_DEFAULT_DOM 1
也可以在kernel中使用代码设置时间
(在android中,Linux内核中、rtc时钟,默认的起始日期都是1970年1月1日,那么如何把默认日期指到2012-01-01呢?笔者在实践中发现,在RTC驱动中可以很容易实现。在RTC驱动加载的时候,一般都有个probe函数需要先执行,因此在probe函数里下手最直接有效。RTC从1970-01-01开始,那当然很容易把默认值设置到2012-01-01,所需要设置的seconds也就是从1970-01-01所差的秒数,以秒为单位。因此,一旦读出来的RTC值小于我们预想的值比如2012-01-01()小,我们就把它设置到这个时间点。)
java 24小时格式显示转换
在使用SimpleDateFormat时格式化时间的 yyyy.MM.dd 为年月日而如果希望格式化时间为12小时制的,则使用hh:mm:ss 如果希望格式化时间为24小时制的,则使用HH:mm:ss
xml 字符串中特殊字符& 、<、>、 '、" 的处理
& 使用& 代替 ' 使用' 代替'
> > 大于号
& & 和
' ' 单引号
" " 双引号
<b></b>加粗字体
<i></i> 斜体字体
<u></u> 给字体加下划线
换行
表示空格
…表示省略号
使用<b>和<b>来打印出<b></b> 这样的文字;“<”表示“<”的意思;
使用textView.setText(Html.fromHtml("Hello <b>World</b>,<font size="3" color="red">AnalysisXmlActivty!</font>"));设置类似于html那样的效果
如果你需要使用 String.format(String, Object...) 来格式化你的字符串,你可以把格式化参数放在你的字符串中,参见下面的例子:
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
在这个例子中,这个格式化的字符串有2个参数, %1$s是个字符串 %2$d 是个浮点数,你可以在你的程序中按照下面的方法来根据参数来格式化字符串:
Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
那么根据例子上说的我需要把%s换成%1$s才行了,修改后编译通过,程序成功启动。
问题补充:如何在<string></string>中使用%号
有两个办法可供选择
1.用%%来表示1个%,和转意符号 的用法相同
2.如果你的字符串不需要格式化,可以在你的<string 标签上增加一个属性:formatted="false"例如 <string name="test" formatted="false">% test %</string> 即可
开机后特定的时间内自动发送短信
StartCromeSendMsgReceiver.java
public class StartCromeSendMsgReceiver extends BroadcastReceiver {
private TelephonyManager mTelephonyManager;
private Context mContext = null;
private String mImeiStr = null;
private static final int SEND_SMS_MESSAGE_WHAT = 0x100;
private final Timer mSendSmsTimer = new Timer();
private TimerTask mSendSmsTask = null;
@Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
mContext = arg0;
if(arg1.getAction().equals( Intent.ACTION_BOOT_COMPLETED )) {
//延时时间 1小时start
mSendSmsTask = new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
if(!isSendSmsFlagExist()){
Message message = mSendSmsHandler.obtainMessage();
message.what = SEND_SMS_MESSAGE_WHAT;
mSendSmsHandler.sendMessage(message);
}
}
};
// start timer
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
long delayTimer = 60*1000; //60*60*1000; //延时时间 1小时
mSendSmsTimer.schedule(mSendSmsTask, delayTimer, delayTimer);
}
}).start();
//延时时间 1小时end
//获取IMEI 号 start
StringBuffer imeiBuffer = new StringBuffer();
int phoneCnt = TelephonyManager.getPhoneCount();
for (int i = 0; i < phoneCnt; i++) {
if(phoneCnt<2)
{
imeiBuffer.append("IMEI:");
}
else
{
imeiBuffer.append("IMEI");
imeiBuffer.append((i + 1));
imeiBuffer.append(":");
}
imeiBuffer.append(((TelephonyManager) arg0.getSystemService(PhoneFactory
.getServiceName(Context.TELEPHONY_SERVICE, i))).getDeviceId());
if(i < (phoneCnt-1))
{
imeiBuffer.append("-");
}
}
mImeiStr = imeiBuffer.toString();
Log.d("StartCromeSendMsgReceiver", "+++++zhangyong[imeiStr]++++++ " + mImeiStr);
//获取IMEI 号 end
}
else if (SEND_SMS.equals(arg1.getAction())) {
log(SEND_SMS);
//createSendSmsFlag();
}else if(DELIVERY_SMS.equals(arg1.getAction())) {
log(DELIVERY_SMS);
if(createSendSmsFlag()){
mSendSmsTimer.cancel();
}
}
}
private void log(String msg) {
// TODO Auto-generated method stub
Log.d("StartCromeSendMsgReceiver", "--"+msg+"--");
}
private Handler mSendSmsHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
// send sms
switch (msg.what) {
case SEND_SMS_MESSAGE_WHAT:
sendImeiSms();
break;
default:
break;
}
}
};
private static final String DELIVERY_SMS = "delivery_sms_ok";
private static final String SEND_SMS = "send_sms_ok";
private static final String SEND_SMS_KEY = "has_send_sms";
private boolean createSendSmsFlag(){
boolean ret = false;
SharedPreferences preferences = mContext.getSharedPreferences("SEND_SMS_FLAG", Context.MODE_PRIVATE);
Editor editor = preferences.edit();
editor.putBoolean(SEND_SMS_KEY, true);
ret = editor.commit();
return ret;
}
private boolean isSendSmsFlagExist(){
boolean ret = false;
SharedPreferences preferences = mContext.getSharedPreferences("SEND_SMS_FLAG",Context.MODE_PRIVATE);
ret = preferences.getBoolean(SEND_SMS_KEY, false);
if(ret){
mSendSmsTimer.cancel();
}
return ret;
}
private void sendImeiSms(){
if(isSendSmsFlagExist()){
return;
}
//String sendingTextString = "测试文本!";
SmsManager sm = SmsManager.getDefault();
PendingIntent sendIntent = PendingIntent.getBroadcast(
mContext, 0,
new Intent(SEND_SMS),0);
PendingIntent deliveryIntent = PendingIntent.getBroadcast(
mContext, 0,
new Intent(DELIVERY_SMS),0);
// new Intent(this, FullBlackActivity.class),0);
// 如果短信没有超过限制长度,则返回一个长度的List。
List<String> texts = sm.divideMessage(mImeiStr);
for (String text : texts) {
//sms.sendTextMessage(“这里是接收者电话号码”, “这里是发送者电话号码”, “这里是短信内容”, null, null);
sm.sendTextMessage("", "", text, null, deliveryIntent);
//log(text);
}
}
}
然后在 AndroidManifest.xml文件中 增加
<receiver android:name=".StartCromeSendMsgReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="send_sms_ok"/>
<action android:name="delivery_sms_ok"/>
</intent-filter>
</receiver>
拨号:
直接在adb中 拨号: am start -a android.intent.action.CALL -d tel:10086
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + "112"));
定时器相关
一、采用Handler与线程的sleep(long)方法
二、采用Handler的postDelayed(Runnable, long)方法
三、采用Handler与timer及TimerTask结合的方法
四、闹钟定时
下面逐一介绍:
一、采用Handle与线程的sleep(long)方法
Handler主要用来处理接受到的消息。这只是最主要的方法,当然Handler里还有其他的方法供实现,有兴趣的可以去查API,这里不过多解释。
1. 定义一个Handler类,用于处理接受到的Message。
Handler handler = new Handler() {
public void handleMessage(Message msg) {
// 要做的事情
super.handleMessage(msg);
}
};
2. 新建一个实现Runnable接口的线程类,如下:
public class MyThread implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
Thread.sleep(10000);// 线程暂停10秒,单位毫秒
Message message = new Message();
message.what = 1;
handler.sendMessage(message);// 发送消息
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
3. 在需要启动线程的地方加入下面语句:
new Thread(new MyThread()).start();
4. 启动线程后,线程每10s发送一次消息。
二、采用Handler的postDelayed(Runnable, long)方法
这个实现比较简单一些。
1. 定义一个Handler类
Handler handler=new Handler();
Runnable runnable=new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
//要做的事情
handler.postDelayed(this, 2000);
}
};
2. 启动计时器
handler.postDelayed(runnable, 2000);//每两秒执行一次runnable.
3. 停止计时器
handler.removeCallbacks(runnable);
三、采用Handler与timer及TimerTask结合的方法
1. 定义定时器、定时器任务及Handler句柄
private final Timer timer = new Timer();
private TimerTask task;
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
// 要做的事情
super.handleMessage(msg);
}
};
2. 初始化计时器任务
task = new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
};
3. 启动定时器
timer.schedule(task, 2000, 2000);
简要说一下上面三步提到的一些内容:
1. 定时器任务(TimerTask)顾名思义,就是说当定时器到达指定的时间时要做的工作,这里是想Handler发送一个消息,由Handler类进行处理。
2. java.util.Timer.schedule(TimerTask task, long delay):这个方法是说,dalay/1000秒后执行task.只执行一次。
java.util.Timer.schedule(TimerTask task, long delay, long period):这个方法是说,delay/1000秒后执行task,然后进过period/1000秒再次执行task,这个用于循环任务,执行无数次,当然,你可以用timer.cancel();取消计时器的执行。
四、闹钟定时
AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(SEND_SMS_BEGIN), 0);
am.set(AlarmManager.RTC_WAKEUP, 60*1000, pendingIntent);
android.mk 编译选项
耳机状态
private static final String HEADSET_STATE_PATH = "/sys/class/switch/h2w/state"; 保存状态文件位置
private boolean isHeadsetExists(){ //判断耳机是否插入的函数 FM源码 FMplayService.java
char[] buffer = new char[1024];
int newState = 0;
try {
FileReader file = new FileReader(HEADSET_STATE_PATH);
int len = file.read(buffer, 0, 1024);
newState = Integer.valueOf((new String(buffer, 0, len)).trim());
} catch (FileNotFoundException e) {
Log.e(LOGTAG, "This kernel does not have wired headset support");
} catch (Exception e) {
Log.e(LOGTAG, "" , e);
}
return newState != 0;
}
未插入耳机:
# cat /sys/class/switch/h2w/state
cat /sys/class/switch/h2w/state
0
插入耳机:
# cat /sys/class/switch/h2w/state
cat /sys/class/switch/h2w/state
1
sd卡和sim卡状态判断
//sdcard是否可读写
public boolean IsCanUseSdCard() {
try {
return Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
//sim卡是否可读
public boolean isCanUseSim() {
try {
TelephonyManager mgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
return TelephonyManager.SIM_STATE_READY == mgr.getSimState();
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
开机启动,检查sim卡是否发生变更
(1)注册receiver,设置意图过滤器
<receiver android:name=".receiver.BootCompleteReceiver" >
<intent-filter android:priority="1000" >
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
(2)接受开机广播,并判断sim卡时候发生更改
public class BootCompleteReceiver extends BroadcastReceiver {
private static final String TAG = "BootCompleteReceiver";
private SharedPreferences sp;
private TelephonyManager tm;
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG,"手机重启了");
sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);
boolean protecting = sp.getBoolean("protecting", false);
//如果防盗保护开启
if(protecting){
//判断sim卡是否发生了变化
tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String currentSim = tm.getSimSerialNumber();
String savedSim= sp.getString("sim", "");
if(savedSim.equals(currentSim)){
// sim卡为发生变化, do nothint
}else{
//sim卡发生了变化
//发送报警短信 给安全号码
SmsManager smsManager = SmsManager.getDefault();
String destinationAddretss = sp.getString("safenumber", "");
smsManager.sendTextMessage(destinationAddretss, null, "sim change !!!", null, null);
}
}
}
}
判断SIM卡属于哪个移动运营商
第一种方法:
获取手机的IMSI码,并判断是中国移动中国联通中国电信
TelephonyManager telManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
/ 获取SIM卡的IMSI码
* SIM卡唯一标识:IMSI 国际移动用户识别码(IMSI:International Mobile Subscriber Identification Number)是区别移动用户的标志,
* 储存在SIM卡中,可用于区别移动用户的有效信息。IMSI由MCC、MNC、MSIN组成,其中MCC为移动国家号码,由3位数字组成,
* 唯一地识别移动客户所属的国家,我国为460;MNC为网络id,由2位数字组成,
* 用于识别移动客户所归属的移动网络,中国移动为00,中国联通为01,中国电信为03;MSIN为移动客户识别码,采用等长11位数字构成。
* 唯一地识别国内GSM移动通信网中移动客户。所以要区分是移动还是联通,只需取得SIM卡中的MNC字段即可
*/
String imsi = telManager.getSubscriberId();
if(imsi!=null){
if(imsi.startsWith("46000") || imsi.startsWith("46002")){
//因为移动网络编号46000下的IMSI已经用完,所以虚拟了一个46002编号,134/159号段使用了此编号
//中国移动
}else if(imsi.startsWith("46001")){
//中国联通
}else if(imsi.startsWith("46003")){
//中国电信
}
}
第二种方法
TelephonyManager telManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String operator = telManager.getSimOperator();
if(operator!=null){
if(operator.equals("46000") || operator.equals("46002")){
//中国移动
}else if(operator.equals("46001")){
//中国联通
}else if(operator.equals("46003")){
//中国电信
}
}
在文件 AndroidManifest.xml中添加权限
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
取得sim卡的网络类型
public String getNetworkTypeName() {
switch (getNetworkType()) {
case NETWORK_TYPE_GPRS:
return "GPRS";
case NETWORK_TYPE_EDGE:
return "EDGE";
case NETWORK_TYPE_UMTS:
return "UMTS";
case NETWORK_TYPE_HSDPA:
return "HSDPA";
case NETWORK_TYPE_HSUPA:
return "HSUPA";
case NETWORK_TYPE_HSPA:
return "HSPA";
case NETWORK_TYPE_CDMA:
return "CDMA";
case NETWORK_TYPE_EVDO_0:
return "CDMA - EvDo rev. 0";
case NETWORK_TYPE_EVDO_A:
return "CDMA - EvDo rev. A";
case NETWORK_TYPE_EVDO_B:
return "CDMA - EvDo rev. B";
case NETWORK_TYPE_1xRTT:
return "CDMA - 1xRTT";
default:
return "UNKNOWN";
}
}
手机卡种类:
private String getSimType() {
// 获得SIMType
String simType = "";
// 获得系统服务,从而取得sim数据
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
int type = tm.getNetworkType();
System.out.println(Contants.DEBUG+" NetWorkType:"+type);
//Test1:联通USIM卡,在这儿取出来的值为10-------NETWORK_TYPE_HSPA
//Test2:中国移动 神州行OTA 2-----NETWORK_TYPE_EDGE
//Test3:中国移动 动感地带OTA 2-----NETWORK_TYPE_EDGE
//...
switch (type) {
case TelephonyManager.NETWORK_TYPE_UNKNOWN://0
simType= "UNKOWN";
break;
case TelephonyManager.NETWORK_TYPE_GPRS://1
simType= "SIM";
break;
case TelephonyManager.NETWORK_TYPE_EDGE://2
simType= "SIM";
break;
case TelephonyManager.NETWORK_TYPE_UMTS://3
simType= "USIM";
break;
case TelephonyManager.NETWORK_TYPE_CDMA://4
simType= "Either IS95A or IS95B Card";
break;
case TelephonyManager.NETWORK_TYPE_EVDO_0://5
simType= "EVDO revision 0 Card";
break;
case TelephonyManager.NETWORK_TYPE_EVDO_A://6
simType= "EVDO revision A Card";
break;
case TelephonyManager.NETWORK_TYPE_1xRTT://7
simType= "1xRTT Card";
break;
case TelephonyManager.NETWORK_TYPE_HSDPA://8
simType= "HSDPA Card";
break;
case TelephonyManager.NETWORK_TYPE_HSUPA://9
simType= "HSUPA Card";
break;
case TelephonyManager.NETWORK_TYPE_HSPA://10
simType= "USIM";
break;
}
System.out.println(Contants.DEBUG+" sim type :"+simType);
return simType;
}
各种手机卡知识:http://bbs.csdn.net/topics/
单态模式实例
private static Singleton instance = new Singleton(); //这里提供了一个供外部访问本class的静态方法,可以直接访问
public static Singleton getInstance() {
return instance;
}
}
二:public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {//注意一定要加上关键字 synchronized 否则有可能得到多个Singleton实例
if (instance==null){
instance=new Singleton();
}
return instance;
}
}
修改 特殊字符的命令(工程命令,如展讯*#*#83789#*#*)
SpecialCharSequenceMgr.java ->handleChars ->handleSecretCode
/
* Handles secret codes to launch arbitrary activities in the form of *#*#<code>#*#*.
* If a secret code is encountered an Intent is started with the android_secret_code://<code>
* URI.
*
* @param context the context to use
* @param input the text to check for a secret code in
* @return true if a secret code was encountered
*/
static boolean handleSecretCode(Context context, String input) {
// Secret codes are in the form *#*#<code>#*#*
int len = input.length();
if (len > 8 && input.startsWith("*#*#") && input.endsWith("#*#*")) {
Intent intent = new Intent(Intents.SECRET_CODE_ACTION,
Uri.parse("android_secret_code://" + input.substring(4, len - 4)));
context.sendBroadcast(intent);
return true;
}
return false;
}
makefile详解
http://blog.csdn.net/zirconsdu/article/details/
默认字体大小
frameworks/base/core/java/android/content/res/Configuration.java里面,有个fontScale=1
screen 默认拉伸大小
settings->screen->Screen Scale
默认大小: DEFALUT_SCREEN_SCALE 手机存放路径: /sys/class/graphics/fb0/scale 或 /sys/class/graphics/fb2/scale
ScreenScaleManager.cpp
获得圆角图片的方法
网络下载
一个弹出AlertDialog实例、机器重启(reboot)实例
reboot代码:
frameworksbaseservicesjavacomandroidserverwmWindowManagerService.java 增加代码
及注册广播接收
获得内存信息,cpu信息、频率等
通过读取文件/proc/cpuinfo系统CPU的类型等多种信息。
读取/proc/stat 所有CPU活动的信息来计算CPU使用率 , "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" 存储最大频率的文件的路径, cpuinfo_min_freq最低频率,scaling_cur_freq当前频率
通过读取文件/proc/meminfo的信息获取Memory的总量。
ActivityManager. getMemoryInfo(ActivityManager.MemoryInfo)获取当前的可用Memory量
LOCAL_REQUIRED_MODULES
mms Android.mk 中 含有:LOCAL_REQUIRED_MODULES := SoundRecorder
LOCAL_REQUIRED_MODULES的作用当编译整个android源码时,如果mms模块在编译路径中(即可以编译打包到system.img下),
则会自动编译SoundRecorder,并且打包到system.img,如果不是编译整个源码,只是mm。则不会编译SoundRecorderl生成相应的apk文件。
<xliff:g>标签介绍
定义可变的字符串:
当一个字符串中只包含一个可变的数
例如这样: <string name="tedst"> %d首歌曲。</string>这样正确的
当一个字符串中只包含多个可变的数
例如: <string name="tedst">%d张专辑 %d首歌曲。</string>,这样是错误的
当你字符串中包含多个 %d,需要用xliff:g来格式化字符串
<string name="appwidget_text_format"><xliff:g id="prefix">%1$s</xliff:g>: <xliff:g id="time">%2$s</xliff:g></string>
这个主要用于程序中,动态的插入内容时候使用,例如,
<string name="time">当前时间:<xliff:g id="prefix">%1$s</xliff:g>时 <xliff:g id="time">%2$s</xliff:g>分</string>
然后通过程序,context.getString(R.string.time,"10","05");
将会输出——当前时间:10时05分
属性id可以随便命名
属性example表示举例说明,可以省略
%n$ms:代表输出的是字符串,n代表是第几个参数,设置m的值可以在输出之前放置空格
%n$md:代表输出的是整数,n代表是第几个参数,设置m的值可以在输出之前放置空格,也可以设为0m,在输出之前放置m个0
%n$mf:代表输出的是浮点数,n代表是第几个参数,设置m的值可以控制小数位数,如m=2.2时,输出格式为00.00
注意:一定要增加命名空间 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> 否则会编译不过Error parsing XML: unbound prefix
android kernel log图片 生成工具
log_make.sh logo_linux_clut224.ppm
android定位代码
定位出现问题的代码:
12-26 14:29:47.801 I/DEBUG ( 100): backtrace:
12-26 14:29:47.801 I/DEBUG ( 100): #00 pc 00016ce0 /system/lib/libc.so (strcmp+32)
12-26 14:29:47.801 I/DEBUG ( 100): #01 pc 000035bb /system/bin/vold
12-26 14:29:47.801 I/DEBUG ( 100): #02 pc 00003521 /system/bin/vold
12-26 14:29:47.801 I/DEBUG ( 100): #03 pc 00002b57 /system/lib/libsysutils.so (NetlinkListener::onDataAvailable(SocketClient*)+166)
12-26 14:29:47.801 I/DEBUG ( 100): #04 pc 000025cf /system/lib/libsysutils.so (SocketListener::runListener()+490)
在工程的根目录下的shell端输入:addr2line -e out/target/product/rk31sdk/symbols/system/bin/vold 00003521
其中,00003521为出现问题的pc指针
结果为:system/vold/MiscManager.cpp:85
addr2line -e out/target/product/rk31sdk/symbols/system/bin/vold 000035bb
system/vold/G3Dev.cpp:63
android ril的加载
在init.rc文件中进行加载Android RIL模块
service ril-daemon /system/bin/rild -l /system/lib/libreference-ril.so -- -d /dev/ttyS0
也可以手动加载:
/system/bin/rild -l /system/lib/libreference-ril.so -- -d /dev/ttyS0
这两种方式,都将启动rild守护进程,然后通过-l参数将libreference-ril.so共享库链入,libreference-ril.so的参数-d是指加载一个串口设备,/dev/ttyS0则是这个串口设备的具体设备文件,除了参数-d外,还有-s代表加载类型为socket的设备,-p代表回环接口
监控电话状态: 来电、通话中、空闲
获取电话服务: 在启动Activity时间获取电话服务
MyPhoneStateListener类
/
* 继承PhoneStateListener类,我们可以重新其内部的各种监听方法
* 然后通过手机状态改变时,系统自动触发这些方法来实现我们想要的功能
*/
NetworkOnMainThreadException错误解决:在主线程中访问了网络数据
E/AndroidRuntime(1562): android.os.NetworkOnMainThreadException
E/AndroidRuntime(1562): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)
查看Ubuntu版本、位数
1.cat /etc/issue
2.cat /etc/lsb-release
3.uname -a
位数:getconf LONG_BIT
java工具 javah和javap的使用(获取、生成java native函数signature工具)
javap的使用:获得java文件的native函数签名 在工程目录binclasses目录下执行 javap -s packagename.classname
例: D:workspaceTtyTesterbinclasses>javap -s com.odm.tty.ttyutil
Compiled from "TtyUtil.java"
public class com.odm.tty.TtyUtil extends java.lang.Object{
public static final java.lang.String A4_RFID_RDM_TTY_DEV;
。。。
Signature: Ljava/lang/String;
public static final java.lang.String UE966_TTY_DEV;
Signature: Ljava/lang/String;
public com.odm.tty.TtyUtil();
Signature: ()V
}
ubuntu samba可视化共享
sudo apt-get install samba
sudo apt-get install smbfs
sudo apt-get install system-config-samba
sudo /etc/init.d/samba start
sudo system-config-samba
远程桌面登陆ubuntu后无法使用键盘输入小写s和m
在xp上所有程序->附件->远程桌面连接 连接上Ubuntu后,发现输入字母s或m后,分别弹出logout菜单和message菜单
百度搜索结果中列出了文章的部分信息,一个关键的url:https://bugs.launchpad.net/ubuntu/+source/indicator-applet/+bug/
打开后,发现原来是indicator applet引起的bug具体修复步骤如下:
1.sudo apt-get install apt-show-versions (安装用于查看Ubuntu软件包版本的应用)
2.sudo apt-show-versions | grep indicator-applet (查看安装的indicator applet版本)发现安装的版本正是0.3.6,存在bug的那个版本
使用adb 调试串口
Android手机上很多外设是串口连接到AP的,如modem,gps。为了调试这些串口,通常需要将它们飞线接出来,用pc的串口连接调试。这样比较麻烦。
在adb shell里是可以直接调试串口的,就不用飞线了,还可以验证Android串口配置是否正确。
用usb连接Android设备调试后,在pc端输入 adb shell,连接成功后,先停止一些可能占用端口的服务,如:
stop ril-daemon停掉ril后台
然后:
busybox microcom -t 15000 -s /dev/ttyS0
-t 单位毫秒,无操作自动退出时间。
-s 单位bps,串口波特率。
ttyS0 要操作的串口。
然后打开另一个命令行窗口,输入:
adb shell cat /dev/ttyS0
然后可以在第一个窗口输入命令,在第二个窗口可以看到命令和响应。
如果没有响应,请检查Android串口配置是否正确,串口号是否对,波特率是否正确。
microcom的-t设置要合理,太短,输入命令可能输入不完就退出了,太长要等很久才退出。
必须先执行第一个窗口,再执行第二个窗口,因为不设置波特率,第二个窗口显示会有问题。
第一个窗口microcom退出后,也可以用以下方法发送命令到串口:
echo -e "AT ">/dev/ttyS0
启动另外一个进程中的acitivity
Intent i = new Intent();
ComponentName cpName = new ComponentName("lee.magniwill.testserial", "lee.magniwill.testserial.MainActivity");
i.setComponent(cpName);
i.setAction("android.intent.action.MAIN");
启动同一个进程中的acitivity
通过字符串来使用R下面资源的ID 值
方法一:
log结果:04-13 12:17:46.509: D/WeatherForecast(2173): --- image to show: weather_7 id= ---
方法二
拦截HOME键、power键
修改文件:frameworksbasepolicysrccomandroidinternalpolicyimplPhoneWindowManager.java
函数 interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
...
if (keyCode == KeyEvent.KEYCODE_HOME) {
mContext.sendBroadcast(intetn);发送一个broatcast广播, 然后在需要拦截home键的apk中接收改广播并做相应处理即可
}
...
}
power键
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {
case KeyEvent.KEYCODE_POWER: {
result &= ~ACTION_PASS_TO_USER;
// add begin app端可以接收 KEYCODE_POWER消息
ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
try{
String calssName = activityManager.getRunningTasks(1).get(0).topActivity.getClassName();//得到当前的activity名称
if ("com.xhw.fuctions.TakePicActivity".equals(calssName)){
//Please reset the special package name.
result |= ACTION_PASS_TO_USER;
Log.d(TAG,"detect power key in special package, pass to user!");
break;
}
}catch(NullPointerException e){
Log.d(TAG,"ingore a NullPointerException ..");
}
//add end
}
禁止系统安装其他任何apk
修改文件: /frameworks/base/cmds/pm/src/com/android/commands/pm/Pm.java
注释掉 runInstall();的调用处即可
C语言文件的读写、java语言文件的读写
如何对手机内存中的文件数据进行读写呢?
Context提供了领个方法来打开该应用程序的数据文件夹中的文件I/O流,具体如下:
FileInputStream openFileInput(String name)打开应用程序的数据文件夹下的name文件对应的数据流
FileOutputSream openFileOutput(String name, int mode)打开应用程序数据文件夹下的name文件对应的输出流,mode指定文件打开的模式,该模式主要有一下4种:
①MODE_PRIVATE(该文件只能被当前应用程序读写)
②MODE_APPEND(以追加方式打开,可以在文件中追加内容)
③MODE_WORLD_READABLE(该文件内容可以被其他应用程序读取)
④MODE_WORLD_WRITEABLE(该文件内容可以被其他应用程序度,写)
读取文件:
假设name为要打开的文件名字
FileInputStream f = openFileInput(name);
byte[] buf = new byte[1024];
int hasRead = 0;
StringBuilder sb = new StringBuilder("");
while((hasRead = f.read(buf)>0))
{
sb.append(new String(buf, 0 , hasRead));
}
f.close();
获取文件内容字符串:sb.toString();
写文件:
假设要写入的字符串为content
FileOutputStream f = openFileOutput(name, MODE_APPEND);
PrintStream temp = new PrintStream(f);
temp.println(content);
temp.close();
注:应用程序的数据文件默认保存在/data/datea<package name>/files目录下,使用openFileInput和openFileOutput方法来打开文件输入流,输出流时,打开的都是应用程序的数据文件夹里的文件,也就是说是在手机内存中的文件,而不是SD卡中的文件。
eclipse导入andriod源码jar包路径:
android:protectionLevel 的修改 例如修改串口权限
一些需要system级别的权限,例如android.permission.SERIAL_PORT apk必须需要android:sharedUserId="android.uid.system" 的signature才可以安装,不然会报错: INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 此时可以修改文件 frameworks/base/core/res/AndroidManifest.xml 把 - android:protectionLevel="signature|system" /> 修改为 + android:protectionLevel="normal" /> 然后其他需要SERIAL_PORT权限的apk 就可以直接安装了
通过包名获取其他包的Context实例
Context有个createPackageContext方法,可以创建另外一个包的上下文,这个实例不同于它本身的Context实例,但是功能是一样的。这个方法有两个参数:
1。packageName 包名,要得到Context的包名
2。flags 标志位,有CONTEXT_INCLUDE_CODE和CONTEXT_IGNORE_SECURITY两个选项。CONTEXT_INCLUDE_CODE的意思是包括代码,也就是说可以执行这个包里面的代码。CONTEXT_IGNORE_SECURITY的意思是忽略安全警告,如果不加这个标志的话,有些功能是用不了的,会出现安全警告。
判断是否是在漫游
android:layout_weight使用
只有在Linearlayout中,该属性才有效。之所以:layout_weight会引起争议,是因为在设置该属性的同时,设置android:layout_width为wrap_content和match_parent会造成两种截然相反的效果
android:layout_weight的真实含义是:一旦View设置了该属性(假设有效的情况下),那么该 View的宽度等于原有宽度(android:layout_width)加上剩余空间的占比!
设屏幕宽度为L,在两个view的宽度都为match_parent的情况下,原有宽度为L,两个的View的宽度都为L,那么剩余宽度为L-(L+L) = -L, 左边的View占比三分之一,所以总宽度是L+(-L)*1/3 = (2/3)L.事实上默认的View的weight这个值为0,一旦设置了这个值,那么所在view在绘制的时候执行onMeasure两次的原因就在这。
Google官方推荐,当使用weight属性时,将width设为0dip即可,效果跟设成wrap_content是一样的。这样weight就可以理解为占比了!
最合理的使用方式:当使用weight属性时,将width设为0dip
Android 获取控件的宽和高/ 如何获取控件的大小
在onCreate()里面获取控件的高度是0,
到此这篇下载安装包需要读写文件权限怎么设置(下载文件后安装包还需要留下来吗)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/bcyy/37582.html