完整代碼如下(重要部分已給註釋)
- manifest文件:
//訪問手機識別碼權限(以便看手機網絡運行商名稱),一個權限即使是動態申請,也要先聲明
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
//手機振動權限
<uses-permission android:name="android.permission.VIBRATE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
//註冊鬧鈴服務
<service android:name=".MessageService"></service>
</application>
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/vibrator_start_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="振動服務啓動" />
<Button
android:id="@+id/vibrator_stop_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="振動服務停止" />
<Button
android:id="@+id/alarm_start_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="鬧鈴服務啓動" />
<Button
android:id="@+id/alarm_stop_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="鬧鈴服務停止" />
<Button
android:id="@+id/SIM_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查看手機網絡運行商名稱" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
activity_main.xml頁面效果展示:
- MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.SystemClock;
import android.os.Vibrator;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
//按鈕的全局變量,以及TAG
private Button vibrator_btn;
private Button alarm_start_btn;
private Button alarm_stop_btn;
private Button SIM_btn;
private String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//各種按鈕定義
vibrator_btn = findViewById(R.id.vibrator_start_btn); //振動器開始振動
vibrator_btn.setOnClickListener(this);
vibrator_btn = findViewById(R.id.vibrator_stop_btn); //振動器停止震動
vibrator_btn.setOnClickListener(this);
alarm_start_btn = findViewById(R.id.alarm_start_btn); //鬧鈴開始服務
alarm_start_btn.setOnClickListener(this);
alarm_stop_btn = findViewById(R.id.alarm_stop_btn); //鬧鈴停止服務
alarm_stop_btn.setOnClickListener(this);
SIM_btn = findViewById(R.id.SIM_btn); //讀取SIM卡,確定手機網絡運營商名稱
SIM_btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
//系統服務-振動器
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
//下面這兩步是爲了後面鬧鈴set和cancle方法寫的
Intent service = new Intent(this, MessageService.class);
PendingIntent pi = PendingIntent.getService(this, 0, service, 0);
//系統服務-鬧鈴
AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
switch (v.getId()) {
//振動器震動
case R.id.vibrator_start_btn:
if (vibrator.hasVibrator()) {
Toast.makeText(getApplicationContext(), "振動器振動五秒", Toast.LENGTH_SHORT).show();
vibrator.vibrate(5 * 1000);
} else {
Toast.makeText(getApplicationContext(), "該設備沒有振動器哦", Toast.LENGTH_SHORT).show();
}
break;
//震動器停止
case R.id.vibrator_stop_btn:
vibrator.cancel();
Toast.makeText(getApplicationContext(), "振動停止", Toast.LENGTH_SHORT).show();
break;
//鬧鈴開始服務
case R.id.alarm_start_btn:
long timer = SystemClock.elapsedRealtime() + 5 * 1000; //設置下一次鬧鈴的時間,這裏定爲5秒
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timer, pi); //Intent service = new Intent(this, MessageService.class)
// PendingIntent pi = PendingIntent.getService(this, 0, service, 0);
Toast.makeText(getApplicationContext(), "五秒後鬧鈴顯示", Toast.LENGTH_SHORT).show();
Log.d(TAG, "五秒後鬧鈴顯示");
break;
//鬧鈴暫停服務
case R.id.alarm_stop_btn:
Toast.makeText(getApplicationContext(), "鬧鈴取消", Toast.LENGTH_SHORT).show();
manager.cancel(pi); //依據pi綁定的intent事件取消鬧鈴
break;
//查看手機網絡運營商名稱
case R.id.SIM_btn:
//系統服務-獲取機識別碼
TelephonyManager telManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
//檢查是否獲取權限,如果沒有則調用ActivityCompat.requestPermissions方法
if (ContextCompat.checkSelfPermission(MainActivity.this,"Manifest.permission.READ_PHONE_STATE") != PackageManager.PERMISSION_GRANTED) {
////123是自定義的,相當於一個標識碼,在後面onRequestPermissionsResult回調方法中會用到
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.READ_PHONE_STATE},123);
}
//係獲取機識別碼
String msi_code = telManager.getSubscriberId();
if(msi_code!=null){
if(msi_code.startsWith("46000") ||msi_code.startsWith("46002")){//因爲移動網絡編號46000下的IMSI已經用完,所以虛擬了一個46002編號,134/159號段使用了此編號
//中國移動
Toast.makeText(getApplicationContext(), "中國移動", Toast.LENGTH_SHORT).show();
}else if(msi_code.startsWith("46001")){
//中國聯通
Toast.makeText(getApplicationContext(), "中國聯通", Toast.LENGTH_SHORT).show();
}else if(msi_code.startsWith("46003")){
//中國電信
Toast.makeText(getApplicationContext(), "中國電信", Toast.LENGTH_SHORT).show();
}else if(msi_code.startsWith("")){
Toast.makeText(getApplicationContext(), "請授予訪問手機識別碼權限", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(getApplicationContext(), "手機識別碼爲" + msi_code, Toast.LENGTH_SHORT).show();
}
}else {
Toast.makeText(this, "請授予訪問手機識別碼權限", Toast.LENGTH_SHORT).show();
}
}
}
//第一個參數就是上面申請權限方法需要記住的標識123,第二個參數爲你的申請權限的數組,第三個參數是授權回調的結果
@Override
public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) {
if (requestCode == 123) {
Toast.makeText(this, "授權成功", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, "請授予訪問手機識別碼權限", Toast.LENGTH_SHORT).show();
}
}
//參數是一個權限,返回true或false,用戶勾選拒絕後不再詢問
public boolean shouldShowRequestPermissionRationale(String permission){
Toast.makeText(this, "默認權限爲拒絕訪問", Toast.LENGTH_SHORT).show();
return false;
}
}
- 鬧鈴中pi繼承的intent用到的類MessageService.java:
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class MessageService extends Service {
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(getApplicationContext(), "五秒鐘到啦!", Toast.LENGTH_SHORT).show();
return super.onStartCommand(intent, flags, startId);
}
}
至於每個類和方法的原理,推薦一個博主寫的文章,比較簡單好懂:
https://www.jianshu.com/p/30edc21c3299