編輯:關於Android編程
本篇博文主要介紹的是Android中的Java服務。
這部分服務大部分都有一個Manager類,其實就是一個RPC調用,用戶通過調用xxxManager的方法,實際上被Binder給遷移到system_server進程中對應的xxxManagerService中對應的方法,並將結果再通過binder帶回。
常用的有如下幾個:
PowerManagerService –> PowerManager
TelecomManager
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
Uri uri=Uri.parse("tel:"+電話號碼);
Intent intent=new Intent(Intent.ACTION_DIAL,uri);
startActivity(intent);
public class MainActivity extends AppCompatActivity {
private TextView tv_phone1;
private TextView tv_phone2;
private TextView tv_phone3;
private TextView tv_phone4;
private TextView tv_phone5;
private TextView tv_phone6;
private TextView tv_phone7;
private TextView tv_phone8;
private TextView tv_phone9;
private TelephonyManager tManager;
private String[] phoneType = {"未知","2G","3G","4G"};
private String[] simState = {"狀態未知","無SIM卡","被PIN加鎖","被PUK加鎖",
"被NetWork PIN加鎖","已准備好"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//①獲得系統提供的TelphonyManager對象的實例
tManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
bindViews();
}
private void bindViews() {
tv_phone1 = (TextView) findViewById(R.id.tv_phone1);
tv_phone2 = (TextView) findViewById(R.id.tv_phone2);
tv_phone3 = (TextView) findViewById(R.id.tv_phone3);
tv_phone4 = (TextView) findViewById(R.id.tv_phone4);
tv_phone5 = (TextView) findViewById(R.id.tv_phone5);
tv_phone6 = (TextView) findViewById(R.id.tv_phone6);
tv_phone7 = (TextView) findViewById(R.id.tv_phone7);
tv_phone8 = (TextView) findViewById(R.id.tv_phone8);
tv_phone9 = (TextView) findViewById(R.id.tv_phone9);
tv_phone1.setText("設備編號:" + tManager.getDeviceId());
tv_phone2.setText("軟件版本:" + (tManager.getDeviceSoftwareVersion()!= null?
tManager.getDeviceSoftwareVersion():"未知"));
tv_phone3.setText("運營商代號:" + tManager.getNetworkOperator());
tv_phone4.setText("運營商名稱:" + tManager.getNetworkOperatorName());
tv_phone5.setText("網絡類型:" + phoneType[tManager.getPhoneType()]);
tv_phone6.setText("設備當前位置:" + (tManager.getCellLocation() != null ? tManager
.getCellLocation().toString() : "未知位置"));
tv_phone7.setText("SIM卡的國別:" + tManager.getSimCountryIso());
tv_phone8.setText("SIM卡序列號:" + tManager.getSimSerialNumber());
tv_phone9.setText("SIM卡狀態:" + simState[tManager.getSimState()]);
}
}
訪問以上API,記得清單文件添加權限
網絡信號強度的單位是dBm(毫瓦分貝),一般用負數表示,正常手機信號變化范圍是從-110dBm (差)到-50dBm(好)之間,如果你比-50dBm還小的話,說明你就站在基站的附近。
另外2G,3G,4G獲得信號強度的方式都是重寫PhoneStateListener的onSignalStrengthsChanged() 方法,當信號強度發生改變的時候就會觸發這個事件,我們可以在這個事件裡獲取信號強度!
手機獲取信號強度代碼示例:
dBm =-113+2*asu這是一個固定公式,asu(獨立信號單元)
public class MainActivity extends AppCompatActivity {
private TextView tv_rssi;
private MyPhoneStateListener mpsListener;
private TelephonyManager tManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tManager = ((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE));
tv_rssi = (TextView) findViewById(R.id.tv_rssi);
mpsListener = new MyPhoneStateListener();
tManager.listen(mpsListener,290);
}
private class MyPhoneStateListener extends PhoneStateListener {
private int asu = 0,lastSignal = 0;
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
asu = signalStrength.getGsmSignalStrength();
lastSignal = -113 + 2 * asu;
tv_rssi.setText("當前手機的信號強度:" + lastSignal + " dBm" );
super.onSignalStrengthsChanged(signalStrength);
}
}
}
getEvdoDbm():電信3G
getCdmaDbm():聯通3G
getLteDbm():4G
不建議使用 android.telephony.gsm.SmsManager
這個類
This class was deprecated in API level 4.
Replaced by android.telephony.SmsManager that supports both GSM and CDMA.
建議使用 android.telephony.SmsManager
這樣發短信,app安裝的時候就可以少寫一條發短信的權限
核心代碼
public void SendSMSTo(String phoneNumber,String message){
//判斷輸入的phoneNumber是否為合法電話號碼
if(PhoneNumberUtils.isGlobalPhoneNumber(phoneNumber)){
//Uri.parse("smsto") 這裡是轉換為指定Uri,固定寫法
Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:"+phoneNumber));
intent.putExtra("sms_body", message);
startActivity(intent);
}
}
這個就需要發短信的權限啦
uses-permission android:name="android.permission.SEND_SMS"/>
我們直接調用SmsManager
為我們提供的短信接口發送短信:
sendTextMessage(destinationAddress, scAddress, text, sentIntent, deliverIntent);
參數依次是:
destinationAddress:收信人的電話號碼 scAddress:短信中心的號碼,null的話使用當前默認的短信服務中心 text:短信內容 sentIntent:短信發送狀態的信息:(發送狀態的Intent) 如果不為null,當消息成功發送或失敗這個PendingIntent就廣播。結果代碼是Activity.RESULT_OK 表示成功,或RESULT_ERROR_GENERIC_FAILURE、RESULT_ERROR_RADIO_OFF、RESULT_ERROR_NULL_PDU 之一表示錯誤。對應RESULT_ERROR_GENERIC_FAILURE,sentIntent可能包括額外的”錯誤代碼”包含一 個無線電廣播技術特定的值,通常只在修復故障時有用。每一個基於SMS的應用程序控制檢測sentIntent。 如果sentIntent是空,調用者將檢測所有未知的應用程序,這將導致在檢測的時候發送較小數量的SMS。 deliverIntent:短信是否被對方收到的狀態信息:(接收狀態的Intent) 如果不為null,當這個短信發送到接收者那裡,這個PendtingIntent會被廣播, 狀態報告生成的pdu(指對等層次之間傳遞的數據單位)會拓展到數據(”pdu”)核心代碼
public void sendSMS(String phoneNumber,String message){
//獲取短信管理器
android.telephony.SmsManager smsManager = android.telephony.SmsManager.getDefault();
//拆分短信內容(手機短信長度限制),貌似長度限制為140個字符,就是
//只能發送70個漢字,多了要拆分成多條短信發送
//第四五個參數,如果沒有需要監聽發送狀態與接收狀態的話可以寫null
List divideContents = smsManager.divideMessage(message);
for (String text : divideContents) {
smsManager.sendTextMessage(phoneNumber, null, text, sentPI, deliverPI);
}
}
可能你還需要監聽短信是否發送成功,或者收信人是否接收到信息,就把下面的加上吧:
//處理返回的發送狀態
String SENT_SMS_ACTION = "SENT_SMS_ACTION";
Intent sentIntent = new Intent(SENT_SMS_ACTION);
PendingIntent sentPI = PendingIntent.getBroadcast(context, 0, sentIntent, 0);
//注冊發送信息的廣播接收者
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context _context, Intent _intent) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(context, "短信發送成功", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE: //普通錯誤
break;
case SmsManager.RESULT_ERROR_RADIO_OFF: //無線廣播被明確地關閉
break;
case SmsManager.RESULT_ERROR_NULL_PDU: //沒有提供pdu
break;
case SmsManager.RESULT_ERROR_NO_SERVICE: //服務當前不可用
break;
}
}
}, new IntentFilter(SENT_SMS_ACTION));
//處理返回的接收狀態
String DELIVERED_SMS_ACTION = "DELIVERED_SMS_ACTION";
//創建接收返回的接收狀態的Intent
Intent deliverIntent = new Intent(DELIVERED_SMS_ACTION);
PendingIntent deliverPI = PendingIntent.getBroadcast(context, 0,deliverIntent, 0);
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context _context, Intent _intent) {
Toast.makeText(context,"收信人已經成功接收", Toast.LENGTH_SHORT).show();
}
}, new IntentFilter(DELIVERED_SMS_ACTION));
AudioManager
AudioManager audiomanage = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
簡單的示例:使用Mediaplayer播放音樂,通過AudioManager調節音量大小與靜音!
對了,先在res下創建一個raw的文件夾,往裡面丟一個MP3資源文件!
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn_start;
private Button btn_stop;
private Button btn_higher;
private Button btn_lower;
private Button btn_quite;
private MediaPlayer mePlayer;
private AudioManager aManager;
//定義一個標志用來標示是否點擊了靜音按鈕
private int flag = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//獲得系統的音頻對象
aManager = (AudioManager) getSystemService(Service.AUDIO_SERVICE);
//初始化mediaplayer對象,這裡播放的是raw文件中的mp3資源
mePlayer = MediaPlayer.create(MainActivity.this, R.raw.countingstars);
//設置循環播放:
mePlayer.setLooping(true);
bindViews();
}
private void bindViews() {
btn_start = (Button) findViewById(R.id.btn_start);
btn_stop = (Button) findViewById(R.id.btn_stop);
btn_higher = (Button) findViewById(R.id.btn_higher);
btn_lower = (Button) findViewById(R.id.btn_lower);
btn_quite = (Button) findViewById(R.id.btn_quite);
btn_start.setOnClickListener(this);
btn_stop.setOnClickListener(this);
btn_higher.setOnClickListener(this);
btn_lower.setOnClickListener(this);
btn_quite.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_start:
btn_stop.setEnabled(true);
mePlayer.start();
btn_start.setEnabled(false);
break;
case R.id.btn_stop:
btn_start.setEnabled(true);
mePlayer.pause();
btn_stop.setEnabled(false);
break;
case R.id.btn_higher:
// 指定調節音樂的音頻,增大音量,而且顯示音量圖形示意
aManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
break;
case R.id.btn_lower:
// 指定調節音樂的音頻,降低音量,只有聲音,不顯示圖形條
aManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_LOWER, AudioManager.FLAG_PLAY_SOUND);
break;
case R.id.btn_quite:
// 指定調節音樂的音頻,根據isChecked確定是否需要靜音
flag *= -1;
if (flag == -1) {
aManager.setStreamMute(AudioManager.STREAM_MUSIC, true); //API 23過期- -
// aManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_MUTE,
// AudioManager.FLAG_SHOW_UI); //23以後的版本用這個
btn_quite.setText("取消靜音");
} else {
aManager.setStreamMute(AudioManager.STREAM_MUSIC, false);//API 23過期- -
// aManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_UNMUTE,
// AudioManager.FLAG_SHOW_UI); //23以後的版本用這個
aManager.setMicrophoneMute(false);
btn_quite.setText("靜音");
}
break;
}
}
}
設置靜音的方法setStreamMute()在API 23版本過期, 可以使用另一個方法adjustStreamVolume(int, int, int),然後第三個屬性設置:
ADJUST_MUTE 或 ADJUST_UNMUTE!
對了,還有:
如果adjustStreamVolume()的第三個參數你設置了振動(Vibrator), 需要在AndroidManifest.xml中添加這個權限!
<uses-permission android:name=”android.permission.VIBRATE”/>
Vibrator
Vibrator vb = (Vibrator)getSystemService(Service.VIBRATOR_SERVICE);
對於Vibrator用的最廣泛的莫過於所謂的手機按摩器類的app
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn_hasVibrator;
private Button btn_short;
private Button btn_long;
private Button btn_rhythm;
private Button btn_cancle;
private Vibrator myVibrator;
private Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//獲得系統的Vibrator實例:
myVibrator = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE);
mContext = MainActivity.this;
bindViews();
}
private void bindViews() {
btn_hasVibrator = (Button) findViewById(R.id.btn_hasVibrator);
btn_short = (Button) findViewById(R.id.btn_short);
btn_long = (Button) findViewById(R.id.btn_long);
btn_rhythm = (Button) findViewById(R.id.btn_rhythm);
btn_cancle = (Button) findViewById(R.id.btn_cancle);
btn_hasVibrator.setOnClickListener(this);
btn_short.setOnClickListener(this);
btn_long.setOnClickListener(this);
btn_rhythm.setOnClickListener(this);
btn_cancle.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_hasVibrator:
Toast.makeText(mContext, myVibrator.hasVibrator() ? "當前設備有振動器" : "當前設備無振動器",
Toast.LENGTH_SHORT).show();
break;
case R.id.btn_short:
myVibrator.cancel();
myVibrator.vibrate(new long[]{100, 200, 100, 200}, 0);
Toast.makeText(mContext, "短振動", Toast.LENGTH_SHORT).show();
break;
case R.id.btn_long:
myVibrator.cancel();
myVibrator.vibrate(new long[]{100, 100, 100, 1000}, 0);
Toast.makeText(mContext, "長振動", Toast.LENGTH_SHORT).show();
break;
case R.id.btn_rhythm:
myVibrator.cancel();
myVibrator.vibrate(new long[]{500, 100, 500, 100, 500, 100}, 0);
Toast.makeText(mContext, "節奏振動", Toast.LENGTH_SHORT).show();
break;
case R.id.btn_cancle:
myVibrator.cancel();
Toast.makeText(mContext, "取消振動", Toast.LENGTH_SHORT).show();
}
}
}
清單文件權限
AlarmManager
關鍵參數說明:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPjxpbWcgYWx0PQ=="這裡寫圖片描述" src="/uploadfile/Collfiles/20160328/20160328091048318.png" title="\" />
要說的是,此例子只在Android 4.4以下的系統可行,5.0以上並不可行,後續如果有5.0 以上AlarmManager的解決方案,到時再補上!另外,這裡用set方法可能有點不准,如果要 更精確的話可以使用setExtra()方法來設置AlarmManager!
首先一個簡單的布局文件:activity_main.xml,另外在res創建一個raw文件夾,把音頻文件丟進去! 另外創建一個只有外層布局的activity_clock.xml作為鬧鐘響時Activity的布局!
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button btn_set;
private Button btn_cancel;
private AlarmManager alarmManager;
private PendingIntent pi;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindViews();
}
private void bindViews() {
btn_set = (Button) findViewById(R.id.btn_set);
btn_cancel = (Button) findViewById(R.id.btn_cancel);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(MainActivity.this, ClockActivity.class);
pi = PendingIntent.getActivity(MainActivity.this, 0, intent, 0);
btn_set.setOnClickListener(this);
btn_cancel.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_set:
Calendar currentTime = Calendar.getInstance();
new TimePickerDialog(MainActivity.this, 0,
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view,
int hourOfDay, int minute) {
//設置當前時間
Calendar c = Calendar.getInstance();
c.setTimeInMillis(System.currentTimeMillis());
// 根據用戶選擇的時間來設置Calendar對象
c.set(Calendar.HOUR, hourOfDay);
c.set(Calendar.MINUTE, minute);
// ②設置AlarmManager在Calendar對應的時間啟動Activity
alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi);
Log.e("HEHE",c.getTimeInMillis()+""); //這裡的時間是一個unix時間戳
// 提示鬧鐘設置完畢:
Toast.makeText(MainActivity.this, "鬧鐘設置完畢~"+ c.getTimeInMillis(),
Toast.LENGTH_SHORT).show();
}
}, currentTime.get(Calendar.HOUR_OF_DAY), currentTime
.get(Calendar.MINUTE), false).show();
btn_cancel.setVisibility(View.VISIBLE);
break;
case R.id.btn_cancel:
alarmManager.cancel(pi);
btn_cancel.setVisibility(View.GONE);
Toast.makeText(MainActivity.this, "鬧鐘已取消", Toast.LENGTH_SHORT)
.show();
break;
}
}
}
鬧鈴頁面的ClockActivity.java
public class ClockActivity extends AppCompatActivity {
private MediaPlayer mediaPlayer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_clock);
mediaPlayer = mediaPlayer.create(this,R.raw.pig);
mediaPlayer.start();
//創建一個鬧鐘提醒的對話框,點擊確定關閉鈴聲與頁面
new AlertDialog.Builder(ClockActivity.this).setTitle("鬧鐘").setMessage("小豬小豬快起床~")
.setPositiveButton("關閉鬧鈴", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mediaPlayer.stop();
ClockActivity.this.finish();
}
}).show();
}
}
核心流程
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
獲得系統提供的AlarmManager服務的對象 Intent設置要啟動的組件: Intent intent = new Intent(MainActivity.this, ClockActivity.class);
PendingIntent對象設置動作,啟動的是Activity還是Service,又或者是廣播! PendingIntent pi = =PendingIntent.getActivity(MainActivity.this, 0, intent, 0);
調用AlarmManager的set( )方法設置單次鬧鐘的鬧鐘類型,啟動時間以及PendingIntent對象! alarmManager.set(AlarmManager.RTC_WAKEUP,c.getTimeInMillis(), pi);
另外假如出現鬧鈴無效的話,你可以從這些方面入手:
1.系統版本或者手機,5.0以上基本沒戲,小米,自行百度吧~ 2.ClockActivity有注冊沒?
3.假如你用的是alarmManager發送廣播,廣播再激活Activity的話,則需要為Intent設置一個flag: i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4. PendingIntent,要寫成getActivity啟動鬧鈴頁面
powermanager
windowmanager
layoutinflater
wallpapermanager
現在,玩微信的朋友有很多,我們用微信不僅可以和朋友家人聊天聯絡,還可以隨時隨地發朋友圈,那麼微信朋友圈怎麼發文字,下面下載吧小編教你一個簡單的方法來用微信朋
QQ厘米秀是騰訊手機QQ新出的功能,玩家在手機QQ聊天中可以放上自己的厘米秀,也能發很多特定的帶有聲音的表情。QQ厘米秀讓用戶在手機QQ聊天中更有趣,而且目
管理log一般有兩種方法,博主推薦大家使用下面的第一種方法:第一種方法:第一步:定義一個logTools工具類,相信你能夠看懂的,誰的log,可以用誰的名字做方法名,如l
/** * @param path 文件保存路徑 * @param data 保存數據 * */ public static void writeImage