Notification에서 앱 실행 with Service

안드로이드 노티피케이션에서 앱 바로가기를 만들어 보자. 

노티피케이션이 없어지지 않기 위해 서비스를 사용한다.

핵심은 서비스로 Notification을 Foreground로 실행 한다. 

그리고 View에서 버튼을 누르면 해당 패키지명을 intent로 날린다. 

이 intent를 받은 브로드케스트를 등록하여 앱을 실행 하도록 처리 하면 된다.

예제 코드 다운로드-

cfile6.uf.1601D4355126E0B70707D8.zip

SVN-

svn checkout –username anonsvn https://dev.naver.com/svn/linker

The password is ‘anonsvn’

Service 구현 내용 

package com.kmshack.qinker.service;


import java.lang.reflect.Method;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
import android.widget.RemoteViews;

import com.kmshack.qinker.MainActivity;
import com.kmshack.qinker.R;
import com.kmshack.qinker.utils.GraphicUtils;

public class QinkerService extends Service {
    public static final String UPDATE = "com.kmshack.qinker.service.update";
    public static final String CMD = "com.kmshack.qinker.service.cmd";
    
    public static final int SERVICE_STATUS = 1;
    
    private Notification mNotification;
    
    private final IQinkerService.Stub mBinder = new IQinkerService.Stub() {
        
        @Override
        public boolean stopService() throws RemoteException {
            return false;
        }
        
        @Override
        public boolean startService() throws RemoteException {
            return false;
        }
        
        @Override
        public boolean isStart() throws RemoteException {
            return false;
        }
    };

    @Override
    public IBinder onBind(Intent arg0) {
        return mBinder;
    }
    
    @Override
    public void onCreate() {
        super.onCreate();
        
        IntentFilter commandFilter = new IntentFilter();
        commandFilter.addAction(UPDATE);
        commandFilter.addAction(CMD);
        registerReceiver(mIntentReceiver, commandFilter);
        
        showNotification();
    }
    
    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
        
        @Override
        public void onReceive(Context context, Intent intent) {
            handleCommand(intent);
        }
    };
    
    private void handleCommand(Intent intent){

        if (intent != null) {
            String action = intent.getAction();
            
            if(action == null)
                return;
            
            if(action.equals(CMD)){
                String packageName = intent.getStringExtra("package_name");
                startActivityForPackageName(packageName);
            }
        }
    }
    
    /**
     * 앱을 실행한다.
     * @param packageName
     */
    private void startActivityForPackageName(String packageName){
        disableStatusBar();
        
        PackageManager pm = getPackageManager();
        Intent app = pm.getLaunchIntentForPackage(packageName);
        
        this.startActivity(app);
    }
    
    /**
     *  상태바를 올린다.
     */
    private void disableStatusBar(){
        try{
            Object service  = getSystemService("statusbar");
            Class statusbarManager = Class.forName("android.app.StatusBarManager");
            
            Method collapse = null;
            
            if (Build.VERSION.SDK_INT  < 17) {
                collapse = statusbarManager.getMethod("collapse");
            } else {
                collapse = statusbarManager.getMethod("collapsePanels");
            }
            collapse.setAccessible(true);
            collapse.invoke(service);
        }catch(Exception ex){
        }
    }
    
    /**
     * 노티피케이션을 표시한다.
     */
    private void showNotification(){
        Intent contentsIntent = new Intent(getApplicationContext(), MainActivity.class);
        
         mNotification =  new Notification.Builder(getApplicationContext())
                                         .setContentIntent(PendingIntent.getActivity(getApplicationContext(), 0, contentsIntent, 0))
                                         .setSmallIcon(R.drawable.ic_launcher)
                                         .setAutoCancel(false).getNotification();
         
         RemoteViews views = new RemoteViews(this.getPackageName(), com.kmshack.qinker.R.layout.notification);

         Intent intent = new Intent(CMD);
         intent.setComponent(new ComponentName(getApplicationContext(), QinkerService.class));
         intent.putExtra("package_name", "com.kmshack.BusanBus");
         
         PendingIntent contentIntent = PendingIntent.getService(getApplicationContext(), 0, intent, 0);
         views.setOnClickPendingIntent(R.id.button1, contentIntent);
         
         views.setImageViewBitmap(R.id.button1, getAppIconResource("com.kmshack.BusanBus"));
         
         mNotification.contentView = views;
         mNotification.flags |= Notification.FLAG_ONGOING_EVENT;
    
        startForeground(SERVICE_STATUS, mNotification);
    }
    
    private Bitmap getAppIconResource(String packageName){
        PackageManager pm = getPackageManager();
        try {
            Drawable icon =  pm.getApplicationIcon(packageName);
            return GraphicUtils.getBitmapForDrawable(icon);
        } catch (NameNotFoundException e) {
        }
        return null;
    }
    
    @Override
    public void onDestroy() {
        stopForeground(true);
        unregisterReceiver(mIntentReceiver);
        super.onDestroy();
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        handleCommand(intent);
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

}



댓글 남기기