如何在前台运行在Android版本低于5.1的应用程序 [英] How to run a application in the foreground on Android versions below 5.1

查看:183
本文介绍了如何在前台运行在Android版本低于5.1的应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


  

我实现了一个小型的定时器应用程序,每当我接到一个电话,它已经开始,就像接到来电后,我开始我的定时器应用程序,并在前台显示计时器。


但它在工作的棒棒糖5.1 的版本中低端版本,它在后台运行。

我需要在所有的设备上运行的前台应用程序,如何实现这一目标?

我的code:

 意图是=新意图(intent.my.action);
it.setComponent(新单元名(context.getPackageName(),timer.class.getName()));
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
。context.getApplicationContext()startActivity(它);

我reciever:

 公共类CallerToActivity扩展广播接收器{
    静态布尔wasRinging = FALSE;
    静态布尔完成= FALSE;
    是SessionManager会议;
    私人布尔启用;    公共无效的onReceive(上下文的背景下,意图意图){
        会话=新是SessionManager(背景);
        字符串状态= intent.getStringExtra(TelephonyManager.EXTRA_STATE);
        启用= session.Is_Enabled();
        如果(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){            Log.d(状态,电话响起来);
        }否则如果(state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){                    它的意图=新意图(intent.my.action);
                    it.putExtra(呼叫,真);
                    it.setComponent(新单元名(context.getPackageName(),timer.class.getName()));
                    it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    。context.getApplicationContext()startActivity(它);        }否则如果(state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
            //调用跌落或拒绝
            Toast.makeText(背景下,手机既不振铃,也不在通话中,
                    Toast.LENGTH_SHORT).show();
            // wasRinging = FALSE;
            完成=真;            System.exit(0);
            Log.d(状态,手机被丢弃);        }    }
}


解决方案

下面是为您解决问题的步骤

1)创建接收器收听电话( PhoneStatReceiver.java

2)创建服务,以显示你上面的电话视图视图(出定时器查看)( HBFloatingHead.java

3)也在里面创建计时器的 HBFloatingHead服务并更新窗口布局,每个定时器。

4)更新您的的Andr​​oidManifest.xml

示例code:
1)PhoneStatReceiver.java

 进口android.app.Service;
进口android.content.BroadcastReceiver;
进口android.content.Context;
进口android.content.Intent;
进口android.telephony.TelephonyManager;
进口android.util.Log;
公共类PhoneStatReceiver扩展广播接收器{    私有静态最后弦乐TAG =PhoneStatReceiver;//私有静态MyPhoneStateListener phoneListener =新MyPhoneStateListener();    私有静态布尔incomingFlag = FALSE;    私人静态字符串incoming_number = NULL;    @覆盖
    公共无效的onReceive(上下文的背景下,意图意图){        如果(intent.getAction()。等于(Intent.ACTION_NEW_OUTGOING_CALL)){
            incomingFlag = FALSE;
            字符串phoneNumber的= intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
            Log.i(TAG,咻+ phoneNumber的);
            startService(上下文);
        }其他{            TelephonyManager TM =
                    (TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE);            开关(tm.getCallState()){
                案例TelephonyManager.CALL_STATE_RINGING:
                    incomingFlag = TRUE;
                    incoming_number = intent.getStringExtra(incoming_number);
                    Log.i(TAG,振铃:+ incoming_number);
                    startService(上下文);
                    打破;
                案例TelephonyManager.CALL_STATE_OFFHOOK:
                    如果(incomingFlag){
                        Log.i(TAG,来袭接受:+ incoming_number);
                    }
                    打破;                案例TelephonyManager.CALL_STATE_IDLE:
                    如果(incomingFlag){
                        Log.i(TAG,进入IDLE);
                    }
                    打破;
            }
        }
    }    公共无效startService(上下文的背景下){
        意向意图=新意图(背景下,HBFloatingHead.class);
        context.startService(意向);
    }
}

2)**更新时间: HBFloatingHead.java **

 进口android.app.Service;
进口android.content.Intent;
进口android.graphics.Color;
进口android.graphics.PixelFormat;
进口android.os.Binder;
进口android.os.CountDownTimer;
进口android.os.IBinder;
进口android.os.Message;
进口android.util.Log;
进口android.view.Gravity;
进口android.view.MotionEvent;
进口android.view.View;
进口android.view.View.OnClickListener;
进口android.view.WindowManager;
进口android.widget.TextView;公共类HBFloatingHead延伸服务{    私人窗口管理mhbWindow;
    私人TextView的mfloatingHead;
    私人意图意图;
    公共静态最后弦乐BROADCAST_ACTION =com.fragmentsample;
    私人最终的IBinder mBinder =新LocalBinder();    公共类LocalBinder扩展粘结剂{
        HBFloatingHead的getService(){
            返回HBFloatingHead.this;
        }
    }    @覆盖
    公众的IBinder onBind(意向意图){
        返回mBinder;
    }    @覆盖
    公共无效的onDestroy(){
        super.onDestroy();
        如果(mfloatingHead!= NULL){
            mhbWindow.removeView(mfloatingHead);
            countDownTimer.cancel();
        }
    }    WindowManager.LayoutParams PARAMS;    @覆盖
    公共无效的onCreate(){
        super.onCreate();
        意图=新意图(BROADCAST_ACTION);        mhbWindow =(窗口管理器)getSystemService(WINDOW_SERVICE);
        mfloatingHead =新的TextView(本);
        mfloatingHead.setBackgroundResource(R.drawable.floating4);
        mfloatingHead.setTextColor(Color.WHITE);
        mfloatingHead.setTextSize(20F);
        mfloatingHead.setHint(00.00秒);
        mfloatingHead.setGravity(Gravity.CENTER);
        mfloatingHead.setPadding(20,20,20,20);        PARAMS =新WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);        params.gravity = Gravity.TOP | Gravity.LEFT;
        params.x = 0;
        params.y = 100;        mhbWindow.addView(mfloatingHead,则params);        尝试{
            mfloatingHead.setOnTouchListener(新View.OnTouchListener(){                私人WindowManager.LayoutParams paramsF =参数;
                私人诠释initialX;
                私人诠释initialY;
                私人浮动initialTouchX;
                私人浮动initialTouchY;                @覆盖
                公共布尔onTouch(视图V,MotionEvent事件){                    开关(event.getAction()){
                        案例MotionEvent.ACTION_UP:                            打破;                        案例MotionEvent.ACTION_DOWN:                            initialX = paramsF.x;
                            initialY = paramsF.y;
                            initialTouchX = event.getRawX();
                            initialTouchY = event.getRawY();                            打破;                        案例MotionEvent.ACTION_MOVE:                            paramsF.x = initialX
                                    +(int)的(event.getRawX() - initialTouchX);
                            paramsF.y = initialY
                                    +(int)的(event.getRawY() - initialTouchY);
                            mhbWindow.updateViewLayout(mfloatingHead,paramsF);                            打破;
                        默认:
                            打破;
                    }                    返回false;
                }
            });
        }赶上(例外五){
            Log.e(#HB#,e.getMessage()的toString());
        }        mfloatingHead.setOnClickListener(新OnClickListener(){            @覆盖
            公共无效的onClick(视图v){                //HBFloatingHead.this.stopSelf();
            }
        });
        startTimer所(1);
    }    @覆盖
    公众诠释onStartCommand(意向意图,诠释标志诠释startId){        返回START_STICKY;
    }    android.os.Handler处理程序=新android.os.Handler(新android.os.Handler.Callback(){
        @覆盖
        公共布尔的handleMessage(消息MSG){
            尝试{
                长秒= msg.what;
                字符串文本=的String.format(%02D秒/ 60)+:
                        +的String.format(%02D秒60%);
                Log.e(TAG,更新的文字:+文字);
                mfloatingHead.setText(文本);
                mhbWindow.updateViewLayout(mfloatingHead,则params);
            }赶上(例外五){
                e.printStackTrace();
            }
            返回false;
        }
    });    CountDownTimer countDownTimer;    私人无效startTimer所(最终诠释minuti){
        countDownTimer =新CountDownTimer(60 * minuti * 1000,500){
            @覆盖
            公共无效onTick(长millisUntilFinished){
                INT秒=(int)的(millisUntilFinished / 1000);                如果(秒大于0)
                    handler.sendEmptyMessage(秒);
                其他
                    HBFloatingHead.this.stopSelf();// Log.d(TIME,mTvTime.getText()的toString());
            }            @覆盖
            公共无效onFinish(){            }
        };        countDownTimer.start();
    }
}



3)创建你的布局在HBFloatingService类注释


4)更新您的Andr​​oidManifest.xml

添加权限

 <使用许可权的android:NAME =android.permission.SYSTEM_ALERT_WINDOW/>
<使用许可权的android:NAME =android.permission.READ_PHONE_STATE> < /使用许可权>
<使用许可权的android:NAME =android.permission.PROCESS_OUTGOING_CALLS>< /使用许可权>


宣布你的Andr​​oid组件

 <接收机器人:名字=。PhoneStatReceiver>
      &所述;意图滤光器>
         <作用机器人:名字=android.intent.action.PHONE_STATE/>
         <作用机器人:名字=android.intent.action.NEW_OUTGOING_CALL/>
      &所述; /意图滤光器>
 < /接收器> <服务
      机器人:名字=。HBFloatingHead
      机器人:出口=真/>

I have implemented a small timer application and it is starting whenever I received a call, Like after receiving an incoming call I am starting my timer application and displaying timer in foreground.

But it is working in lollipop 5.1 version in lower end version it is running in background.

I need to run application in foreground in all devices, how to achieve this?

My code:

Intent it = new Intent("intent.my.action");
it.setComponent(new ComponentName(context.getPackageName(), timer.class.getName()));
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.getApplicationContext().startActivity(it);

My reciever:

public class CallerToActivity extends BroadcastReceiver {
    static boolean wasRinging = false;
    static boolean finish = false;
    SessionManager session;
    private boolean enable;

    public void onReceive(Context context, Intent intent) {
        session = new SessionManager(context);
        String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
        enable = session.Is_Enabled();
        if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {

            Log.d("Status", "Phone is Ringing");
        } else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {

                    Intent it = new Intent("intent.my.action");
                    it.putExtra("Call", "true");
                    it.setComponent(new ComponentName(context.getPackageName(), timer.class.getName()));
                    it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.getApplicationContext().startActivity(it);



        } else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
            // Call Dropped or rejected
            Toast.makeText(context, "phone is neither ringing nor in a call",
                    Toast.LENGTH_SHORT).show();
            // wasRinging = false;
            finish = true;

            System.exit(0);
            Log.d("Status", "Phone is dropped");

        }

    }
}

解决方案

Here are the steps to solve your problem
1) Create Receiver to listen call (PhoneStatReceiver.java)
2) Create service to show view (Ex. Timer View) above your phone call view (HBFloatingHead.java)
3) Also create timer inside HBFloatingHead service and update window layout as per timer.
4) Update your AndroidManifest.xml

Example code: 1) PhoneStatReceiver.java

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.util.Log;


public class PhoneStatReceiver extends BroadcastReceiver{

    private static final String TAG = "PhoneStatReceiver";

//        private static MyPhoneStateListener phoneListener = new MyPhoneStateListener();

    private static boolean incomingFlag = false;

    private static String incoming_number = null;

    @Override
    public void onReceive(Context context, Intent intent) {

        if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)){
            incomingFlag = false;
            String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
            Log.i(TAG, "call OUT:"+phoneNumber);
            startService(context);
        }else{

            TelephonyManager tm =
                    (TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE);

            switch (tm.getCallState()) {
                case TelephonyManager.CALL_STATE_RINGING:
                    incomingFlag = true;
                    incoming_number = intent.getStringExtra("incoming_number");
                    Log.i(TAG, "RINGING :"+ incoming_number);
                    startService(context);
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    if(incomingFlag){
                        Log.i(TAG, "incoming ACCEPT :"+ incoming_number);
                    }
                    break;

                case TelephonyManager.CALL_STATE_IDLE:
                    if(incomingFlag){
                        Log.i(TAG, "incoming IDLE");
                    }
                    break;
            }
        }
    }

    public void startService(Context context){
        Intent intent = new Intent(context, HBFloatingHead.class);
        context.startService(intent);
    }
}

2) **Updated HBFloatingHead.java**

 import android.app.Service;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Binder;
import android.os.CountDownTimer;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.TextView;

public class HBFloatingHead extends Service {

    private WindowManager mhbWindow;
    private TextView mfloatingHead;
    private Intent intent;
    public static final String BROADCAST_ACTION = "com.fragmentsample";


    private final IBinder mBinder = new LocalBinder();

    public class LocalBinder extends Binder {
        HBFloatingHead getService() {
            return HBFloatingHead.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mfloatingHead != null) {
            mhbWindow.removeView(mfloatingHead);
            countDownTimer.cancel();
        }
    }

    WindowManager.LayoutParams params;

    @Override
    public void onCreate() {
        super.onCreate();
        intent = new Intent(BROADCAST_ACTION);

        mhbWindow = (WindowManager) getSystemService(WINDOW_SERVICE);
        mfloatingHead = new TextView(this);
        mfloatingHead.setBackgroundResource(R.drawable.floating4);
        mfloatingHead.setTextColor(Color.WHITE);
        mfloatingHead.setTextSize(20f);
        mfloatingHead.setHint("00.00 sec");
        mfloatingHead.setGravity(Gravity.CENTER);
        mfloatingHead.setPadding(20, 20, 20, 20);

        params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);

        params.gravity = Gravity.TOP | Gravity.LEFT;
        params.x = 0;
        params.y = 100;

        mhbWindow.addView(mfloatingHead, params);

        try {
            mfloatingHead.setOnTouchListener(new View.OnTouchListener() {

                private WindowManager.LayoutParams paramsF = params;
                private int initialX;
                private int initialY;
                private float initialTouchX;
                private float initialTouchY;

                @Override
                public boolean onTouch(View v, MotionEvent event) {

                    switch (event.getAction()) {
                        case MotionEvent.ACTION_UP:

                            break;

                        case MotionEvent.ACTION_DOWN:

                            initialX = paramsF.x;
                            initialY = paramsF.y;
                            initialTouchX = event.getRawX();
                            initialTouchY = event.getRawY();

                            break;

                        case MotionEvent.ACTION_MOVE:

                            paramsF.x = initialX
                                    + (int) (event.getRawX() - initialTouchX);
                            paramsF.y = initialY
                                    + (int) (event.getRawY() - initialTouchY);
                            mhbWindow.updateViewLayout(mfloatingHead, paramsF);

                            break;
                        default:
                            break;
                    }

                    return false;
                }
            });
        } catch (Exception e) {
            Log.e("#HB#", e.getMessage().toString());
        }

        mfloatingHead.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                //HBFloatingHead.this.stopSelf();


            }
        });
        startTimer(1);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        return START_STICKY;
    }

    android.os.Handler handler = new android.os.Handler(new android.os.Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            try {
                long seconds = msg.what;
                String text = String.format("%02d", seconds / 60) + ":"
                        + String.format("%02d", seconds % 60);
                Log.e("TAG", "Updated text : " + text);
                mfloatingHead.setText(text);
                mhbWindow.updateViewLayout(mfloatingHead, params);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return false;
        }
    });

    CountDownTimer countDownTimer;

    private void startTimer(final int minuti) {
        countDownTimer = new CountDownTimer(60 * minuti * 1000, 500) {
            @Override
            public void onTick(long millisUntilFinished) {
                int seconds = (int) (millisUntilFinished / 1000);

                if (seconds > 0)
                    handler.sendEmptyMessage(seconds);
                else
                    HBFloatingHead.this.stopSelf();

//              Log.d("TIME", mTvTime.getText().toString());
            }

            @Override
            public void onFinish() {

            }
        };

        countDownTimer.start();
    }
}


3) Create your layout as commented in HBFloatingService class
4) Update your AndroidManifest.xml

Add Permissions

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_PHONE_STATE">     </uses-permission>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"></uses-permission> 


Declare your Android components

 <receiver android:name=".PhoneStatReceiver">
      <intent-filter>
         <action android:name="android.intent.action.PHONE_STATE" />
         <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
      </intent-filter>
 </receiver>

 <service
      android:name=".HBFloatingHead"
      android:exported="true" />

这篇关于如何在前台运行在Android版本低于5.1的应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆