本人微信公众号"aeolian"~

HttpClient将手机上的数据发送到服务器

 到官网下载jar包,下载GA发布版本即可

在项目中将httpclient-4.5.5.jar、httpcore-4.4.9.jar、httpmime-4.5.5.jar、commons-logging-1.2.jar四个jar包放进lib中

服务器端

@Controller
@RequestMapping("/HttpInfoController")
public class GetHttpInfoController {
    @RequestMapping("/getAndroid")
    @ResponseBody
    public String getAndroid(HttpServletRequest request, HttpServletResponse response) {
        String data = request.getParameter("data");
        try
        {
            String path="/root/Android.log";
            File file=new File(path);
            //若不存在即创建文件
            if(!file.exists())
                file.createNewFile();

            //创建文件输入流
            FileOutputStream out=new FileOutputStream(file,true); //如果追加方式用true

            StringBuffer sb=new StringBuffer();
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            sb.append("-----------"+sdf.format(new Date())+"------------\n");
            sb.append(data+"\n");
            //写入
            out.write(sb.toString().getBytes("utf-8"));//注意需要转换对应的字符集
            out.close();
        }
        catch(IOException ex)
        {
            System.out.println(ex.getStackTrace());
            return "success";
        }finally {

        }
        return "success";
    }
}

移动端

发送请求工具类

package com.autumn.tools;

import android.icu.util.Output;
import android.util.Log;

import com.autumn.pojo.GPSPojo;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;


public class HttpClientUtil {
    public static void main(String[] args) throws IOException,
            KeyManagementException, NoSuchAlgorithmException {
        //post(URL,"Android项目HttpClient手动发送post()");
        //postAndroid(URL,"Android项目HttpClient手动发送postAndroid()");
        GPSPojo gpsPojo = new GPSPojo();
        gpsPojo.setUserId("qyid1");
        gpsPojo.setUserName("autumn");
        postObjectAndroid(URL,gpsPojo);
    }
    //通用记录到日志url
    public static String URL = "http://*****/getAndroid";
    public static String URL_LOGIN = "http://***/forAndroid";
    /**
     * 正常环境中使用
     * @param data
     */
    public static void post(String url,String data) {
        // 实例化httpclient
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // 创建post实例
        if(url==null||url.isEmpty()){
            url = URL;
        }
        HttpPost httpPost = new HttpPost(URL);
        httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");

        // 添加参数
        List params = new ArrayList();
        params.add(new BasicNameValuePair("data", data));

        CloseableHttpResponse response = null;
        // 将参数放入post实例
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            // httpclient执行操作返回response
            response = httpclient.execute(httpPost);
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 安卓使用放入data:json格式的对象
     * @param data
     */
    public static void postAndroid(final String url,final String data) {
        Runnable runnable = new Runnable() {
            public void run() {

                // 实例化httpclient
                // CloseableHttpClient httpclient = HttpClients.createDefault();   使用会与android核心包起冲突
                org.apache.http.client.HttpClient httpclient = new DefaultHttpClient();
                // 创建post实例
                HttpPost httpPost = null;
                if(url==null||url.isEmpty()){
                    httpPost = new HttpPost(URL);
                }else{
                    httpPost = new HttpPost(url);
                }
                httpPost.setHeader("Content-type",
                        "application/x-www-form-urlencoded");

                // 添加参数
                List params = new ArrayList();
                params.add(new BasicNameValuePair("data", data));

                // CloseableHttpResponse response = null;   使用会与android核心包起冲突
                HttpResponse response = null;
                // 将参数放入post实例
                try {
                    httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
                    response = httpclient.execute(httpPost);
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (ClientProtocolException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
        new Thread(runnable).start();
    }

    /**
     * 安卓使用放Http发送Object对象中的每一个字段作为参数,值作为参数值
     * @param data
     */
    public static void postObjectAndroid(final String url,final Object data) {
        Runnable runnable = new Runnable() {
            public void run() {

                // 实例化httpclient
                // CloseableHttpClient httpclient = HttpClients.createDefault();   使用会与android核心包起冲突
                org.apache.http.client.HttpClient httpclient = new DefaultHttpClient();
                // 创建post实例
                HttpPost httpPost = null;
                if(url==null||url.isEmpty()){
                    httpPost = new HttpPost(URL);
                }else{
                    httpPost = new HttpPost(url);
                }
                httpPost.setHeader("Content-type",
                        "application/x-www-form-urlencoded");

                // 添加参数
                List params = new ArrayList();
                Class dataClass = data.getClass();
                Field[] declaredFields = dataClass.getDeclaredFields();
                for (Field field:declaredFields){
                    try {
                        field.setAccessible(true);
                        if(field.get(data)!=null){   //字段值不为null,则作为参数
                            params.add(new BasicNameValuePair(field.getName(),field.get(data).toString()));
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
                //params.add(new BasicNameValuePair("data", data));

                // CloseableHttpResponse response = null;   使用会与android核心包起冲突
                HttpResponse response = null;
                // 将参数放入post实例
                try {
                    httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
                    response = httpclient.execute(httpPost);
                    if (response.getStatusLine().getStatusCode() == 200) {//如果返回成功则解析
                        HttpEntity responseEntity = response.getEntity();
                        //方法一
                        InputStream inputStream = responseEntity.getContent();
                        StringBuilder stringBuilder = new StringBuilder();
                        byte[] temp = new byte[1024];
                        OutputStream outputStream = new ByteArrayOutputStream();
                        int len =0;
                        while((len=inputStream.read(temp))!=-1){
                            outputStream.write(temp,0,len);
                            String result = new String(temp);
                            stringBuilder.append(result);
                        }
                        Log.i("stringBuilder",stringBuilder.toString());
                        //方法二
                        /*String str = EntityUtils.toString(responseEntity, HTTP.UTF_8);
                        Log.i("str",str);*/

                    }
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (ClientProtocolException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
        new Thread(runnable).start();
    }

}

 

消息通知监听ListenerService

package com.autumn.service;

import android.app.Notification;
import android.os.Bundle;
import android.service.notification.StatusBarNotification;
import com.autumn.tools.HttpClientUtil;

/**
 * 消息监听
 * @author Autumn
 */
public class NotificationMonitorService extends android.service.notification.NotificationListenerService {
    // 在收到消息时触发
    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        // TODO Auto-generated method stub
        Bundle extras = sbn.getNotification().extras;
        // 获取接收消息APP的包名
        String notificationPkg = sbn.getPackageName();
        // 获取接收消息的抬头
        final String notificationTitle = extras.getString(Notification.EXTRA_TITLE);
        // 获取接收消息的内容
        String notificationText = extras.getString(Notification.EXTRA_TEXT);
        if(notificationTitle==null&¬ificationText==null){   //如果为空,则不执行
            return;
        }
        //发送数据
        HttpClientUtil.postAndroid("autumn app: "+notificationPkg+" title: " + notificationTitle + " & " + notificationText);
        //Log.e("listener_post", "autumn app post: "+notificationPkg+" title: " + notificationTitle + " & " + notificationText);
    }
    
    // 在删除消息时触发
    @Override
    public void onNotificationRemoved(StatusBarNotification sbn) {
        // TODO Auto-generated method stub
        Bundle extras = sbn.getNotification().extras;
        // 获取接收消息APP的包名
        String notificationPkg = sbn.getPackageName();
        // 获取接收消息的抬头
        String notificationTitle = extras.getString(Notification.EXTRA_TITLE);
        // 获取接收消息的内容
        String notificationText = extras.getString(Notification.EXTRA_TEXT);
        //Log.e("listener_remove", "autumn app post: "+notificationPkg+" title: " + notificationTitle + " & " + notificationText);
    }
    
}

要在AndroidManifest.xml注册service和权限

    
    <uses-permission android:name="android.permission.INTERNET" />
    
    <service android:name="com.autumn.service.NotificationMonitorService"     
             android:label="NotificationMonitor"
             android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
             <intent-filter>
                <action android:name="android.service.notification.NotificationListenerService" />
             intent-filter>
    service>

启动监听服务分两种方式,一个是跳到授权界面并启动服务,第二个直接启动服务

Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
startActivity(intent);   //授权,跳到授权界面并启动服务

Intent startIntent = new Intent(this, BackService.class);
startService(startIntent);   //启动服务

然后在MainActivity.java中添加运行service,onCreate()方法中代码

        Intent intent_listener=new Intent(this, NotificationMonitorService.class);
        intent_listener.setAction("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
        startService(intent_listener);  //启动监听后台服务
        
        setContentView(R.layout.activity_main);

        //获取启动服务按钮
        Button btn_getAcc = (Button) findViewById(R.id.bt1);
        //按钮点击事件
        btn_getAcc.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                String string = Settings.Secure.getString(getContentResolver(),
                        "enabled_notification_listeners");
                if (!string.contains(NotificationMonitorService.class.getName())) {
                    Toast.makeText(MainActivity.this, "未获得权限,请选择允许权限", Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(MainActivity.this, "已经获得权限", Toast.LENGTH_SHORT).show();
                }
                
                Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");  
                startActivity(intent);// 来授权  会跳到授权界面
            }
        });

软件自启

软件开关机自启广播

package com.autumn.receiver;

import com.autumn.service.NotificationMonitorService;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

/**
 * 软件自启代码
 * @author Autumn
 */
public class BroReceiver extends BroadcastReceiver {
    public BroReceiver() {
    }
    
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
            Intent intent1=new Intent(context, NotificationMonitorService.class);
            intent1.setAction("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
            context.startService(intent1);  //启动监听服务
        }
    }
}

AndroidManifest.xml中注册


<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

<receiver android:name="com.autumn.receiver.BroReceiver" android:enabled="true" android:exported="true" > <intent-filter android:priority="1000" > <action android:name="android.intent.action.BOOT_COMPLETED" /> <category android:name="android.intent.category.LAUNCHER" /> intent-filter> receiver>

 

服务器查看接受数据 tail -f Android.log

《HttpClient将手机上的数据发送到服务器》

注意事项:

1.httpclient出现和system/framework中的jar包起冲突情况

这是由于使用了CloseableHttpClient造成的,把

CloseableHttpClient httpclient = HttpClients.createDefault();
CloseableHttpResponse httpResponse = httpclient.execute(httpRequest);

替换成

HttpClient httpclient = new DefaultHttpClient();
HttpResponse httpResponse = httpclient.execute(httpRequest);

2.主线程中不可以存在http请求,要另起线程

        Runnable runnable = new Runnable() {
            public void run() {
                HttpClient.postAndroid("Notification posted 通知标题: " + "通知内容:");
            }
        };
        new Thread(runnable).start();

3.本人用的MIUI9系统,会出现每次点进去都要选择权限等一系列问题解决方案如下。

1.设置->更多设置->系统安全->通知使用权

2.软件设为自启动

点赞

Leave a Reply

Your email address will not be published. Required fields are marked *